2

Note: I have read the answer to this question, but found it unsatisfactory, probably because I don't understand enough about security.

I'm referring to a frontend server-side rendered SPA + a backend API, which needs to use cookies, and needs persistent login. Since I need cookies for server-side authentication, I want to eliminate any usage of LocalStorage for authentication (to (further) mitigate XSS)

  1. Upon successful login, an httpOnly cookie is set by backend, auth_token, and is sent back to the client's browser. This contains the authentication token. It will be sent automatically with each request (as is every cookie).

  2. Another cookie is set by backend, csrftoken, which is a long random string.

  3. The frontend application (a JS framework) does NOT refer, store, or save auth_token anywhere in its code.

  4. The frontend application code checks to see if there's a csrftoken cookie present, and if there is, attaches it as a custom header, X-CSRFToken, with the same value as csrftoken.

  5. The server authenticates a user successfully if:

    5.1 auth_token present and valid (database token)

    5.2 csrftoken cookie + X-CSRFToken header are present and not empty

    5.3 csrftoken cookie + X-CSRFTokenare equal

Here's my question: What's the difference between having csrftoken (and therefore the X-CSRFToken header) as a very long, random string, and something like 1? It is clearly stated in multiple places that a CSRF attacker can't create custom headers..If the difference is "brute-forcing" the CSRF token, please explain what that would entail, and how the X-CSRFToken header be set?

  • Step 1 and 3 are contradictory. You clam that the client stores auth_token and send it back with every request, then you claim that the client never stores auth_token. – MechMK1 Oct 15 at 9:14
  • @MechMK1 - I've edited my question. auth_token is sent with every request because it's a cookie. My second note about the client not storing is that the JS application isn't storing it (obviously it can't because it's an HttpOnly cookie). Is it clear now what's happening? – zerohedge Oct 15 at 9:16
  • 1
    @MechMK1 1. I don't know much, I come to learn from the friendly community of SE. 2. You are referring to the client as the browser, but i've edited the question to indicate that I mean my JS application, the frontend application, right after your first comment. You can call it a typo, I apologize. Does that satisfy you? – zerohedge Oct 15 at 9:20
  • 1
    @GeirEmblemsvag - No. sorry. That isn’t my question. I shouldn’t have mentioned XSS at all to avoid confusion. My question is at the end of my OP and refers to CSRF, in particular, why in this pattern it needs to be random, etc... – zerohedge Oct 15 at 12:53
  • 1
    @zerohedge Don't worry, the current version of your question is plenty clear. It's just easy to have some miscommunication on forums like this. – Conor Mancone Oct 15 at 13:00
3

This question is your friend:

CSRF protection with custom headers (and without validating token)

In essence, if you opt to make your X-CSRFToken header something simple like 1, you are falling back simply on the presence of your custom header for CSRF protection. If you have a fixed CSRF token for all users, then an attacker will easily be able to figure this out and will therefore know the CSRF token for all users. Since this will naturally match the cookie you create for all users, an attacker will therefore automatically circumvent the cookie matching requirement of your CSRF system.

Therefore (repeating myself here), your CSRF protection will effectively boil down to the fact that you're checking for the presence of a custom header in the request. This is not a crazy thing to do, because there are currently no known ways for an attacker to set a custom header in a CSRF attack. So for now, this would actually be sufficient protection. In that case though you also might as well not bother with the cookie, since it isn't actually providing additional protection.

Generally though (per the question I linked to above and its answers) checking only for a custom header is discouraged because things change and you never know when someone might find a way to set a custom header on a CSRF attack. If that were to happen, your protection would no longer work and you would be vulnerable to a CSRF attack.

In the end though you have to decide what is the best way to balance the cost (of implementing this security measure) vs the benefit (of securing your application), and decide what security steps work best for you. If your application is an anonymous website for voting on favorite cat pictures, I'd say just stick with the custom-header protection. If you're securing the nuclear launch codes though, I'd go for proper CSRF protection (and a whole lot more!).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.