29

I'm trying to fully understand the concept behind CSRF, and more importantly, how to protect against it.

Can I assume, using only CSRF, so no XSS or other techniques, a hacker cannot know the value of the random anti-CSRF token I insert into the page?

1
  • 2
    You might want to look at the more recently introduced SameSite flag for cookies as well as (part of) your protection against CSRF.
    – caw
    Commented Jan 18, 2019 at 17:03

1 Answer 1

23

Your understanding is correct.

Background

The simplest way to think of a CSRF attack is that your browser has two tabs open - Tab A: www.mybank.com and Tab B: www.attacker.com.

(As @Alex points out in comments, multiple tabs are not necessary; the important part is that your browser has auth cookies for mybank.com in memory. CSRF can equally happen if you were on mybank.com earlier and then without logging out, browse to attacker.com)

Cookies

Historically, it was common to store your auth / session token in a cookie. This is convenient for pure HTML pages (ie no javascript) because when you send a request to www.mybank.com, the browser will automatically attach any relevant auth cookies -- no action required on the part of your HTML page in order to maintain the session. CSRF is an attack on cookie-based auth tokens: if Tab B (www.attacker.com) sends a request to www.mybank.com, the browser will automatically attach the authentication cookie, ie Tab B can send requests as if they were logged in to Tab A.

Solutions

You need to put your auth / session token somewhere that's not a cookie. Remembering that Tab B can't see any of the content in Tab A, there are any number of places you could put the auth / session token:

  • somewhere on the HTML page (maybe in a hidden HTML element),
  • or in a non-cookie HTTP Response Header,
  • or if this is an API then you could put it in a token: ___ field of the JSON body, etc.

It really doesn't matter where, so long as it's not in a cookie.

For completeness, I'll add that your anti-CSRF token needs to be long and random enough to prevent the attacker from guessing it. For example, if you use the same anti-CSRF token for all users, or you derive it from the user name, then it doesn't matter that Tab B can't read the content of Tab A because they can guess the token and include it in their blind CSRF request.


References

8
  • 6
    As an example, I worked on a project where the CSRF token was accidentally being set to a simple timestamp of the request. To a layperson, it looked like a random long number, but to a hacker or developer, it was immediately clear that it was not random at all and simply a millisecond timestamp. That would be easy to guess for an attacker, so a pretty pointless implementation. In other words, it seems dumb to use the same token for every user, but when you see a real mistake like this, you realize that it does happen from time to time.
    – JPhi1618
    Commented Jan 17, 2019 at 19:54
  • somewhere on the HTML page (maybe in a hidden HTML element) Doesn't sound very safe to me. It prevents CSRF, but makes you vulnerable to XSS.
    – Yay295
    Commented Jan 18, 2019 at 2:56
  • 2
    @Yay295 How so? Commented Jan 18, 2019 at 2:58
  • 5
    @Yay295 Exactly, that's the whole point of a CSRF token, the server hands it to the page (and any scripts running on it) so that they can hand it back with the next request. I don't see the problem...? Commented Jan 18, 2019 at 3:06
  • 1
    @Yay295 That's a different problem with a different solution. This solves CSRF, not XSS. Making your site protect against one security breach doesn't make it immune (or necessarily susceptible) to another. Cookies are accessible via executed scripts anyways, so I fail to see your point to start with (i.e. if you were vulnerable to CSRF because you're storing the token in the cookie, and you are currently vulnerable to XSS... adding the token to the HTML isn't losing any protection; the scripts could get at the cookie with document.cookie)
    – Delioth
    Commented Jan 18, 2019 at 18:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .