6

According to Cross-Site Request Forgery (CSRF) Prevention Cheat Sheet , the recommended solution to protect web site from CSRF attacking is to implement Synchronizer Token Pattern. And This requires the token to be random or unique.

And recently, we are trying to apply this to our web site. And one of my colleges wants to generate the token by encrypting the current sign-in user's id concatenating a timestamps with a safely kept password. And then append the token into the form.

When user sign in, we set a logged-in user id cookie under our site domain and the root path /. So if we can find this special cookie, then we get the logged-in user's id.

When we get the token, we try to decrypt it to get an user id and an timestamps. We then compare the user id with the current sign-in user's id and use the timestamps to check if the token timeouts.

So I want to know if this works and what's the pros and cons?

The reason why we try to do this is that we try to avoid sessions. Some frameworks like Struts2 have build-in implementations based on sessions.

11
  • 14
    If you can append the password, does that mean you guys are actually storing the password clear text in such a way that the application can directly access the passwords? Because I think you might have another problem than CSRF ... Commented Jan 11, 2013 at 9:38
  • @LucasKauffman Yes, the application can directly access the password used to encrypt the data. Even worse, we use only one password for all tokens. Besides the password problem, how about the CSRF problem?
    – George
    Commented Jan 11, 2013 at 9:46
  • How do you identify users? i.e. what do you have in the cookie instead of the session id? And what kind of crypto do you apply to it? Commented Jan 11, 2013 at 11:18
  • 2
    I think you're missing some context here. As you comment below, that you are not using sessions (why not? What is the architecture? Does this affect the CSRF issue?) - how are users identified and authenticated? Is CSRF even an issue at all? This would be based either on a sessionId cookie, or HTTP Authentication Headers. Otherwise, CSRF is probably not an issue at all. Either way, this could greatly affect the efficacy of any solution provided. Please edit your question to add all relevant context.
    – AviD
    Commented Jan 11, 2013 at 11:51
  • 2
    wayyy over kill when all you need is a random number
    – rook
    Commented Jan 11, 2013 at 17:01

3 Answers 3

13

This is probably a bad mechanism, since it violates Kerckhoff's principle. If an attacker knows how your "encryption" works, he can just encrypt his own CSRF blob for a specific user and use it in targeted attacks.

CSRF leverages the fact that your browser will send a cookie containing a session ID that authenticates you to the server, even if the request is generated by an automated script. In order to protect yourself against this, you just need to require a token that is unknown to an attacker, and that is not automatically sent by the browser without direct instruction. The standard way to do this is to generate a random value, known as a CSRF token, and add it to the parameters of a POST request. As long as the target script verifies the CSRF token somehow, you're protected.

The simplest way to do this is to generate a random CSRF token when the session starts, and store it as a session variable. It can then be injected into forms that require CSRF protection, and checked by the target script.

Adding any "extras" to this scheme, like encryption / timestamps is snakeoil - i.e. it provides no real security and complicates the scheme, which results in a potentially greater attack surface. Remember: don't be a Dave!

8
  • We wasn't allowed to use session at all. Because if we store the token in session, we must maintain a distributed session due to multiple application servers. So we try to avoid sessions.
    – George
    Commented Jan 11, 2013 at 10:06
  • 2
    So how does your server know that a user is "logged in"?
    – Polynomial
    Commented Jan 11, 2013 at 10:40
  • When user signed in, we set a logged-in user id cookie under our site domain and the root path /. So if we can find this special cookie, then we get the logged-in user's id.
    – George
    Commented Jan 12, 2013 at 12:28
  • 1
    @George So if the user changes the cookie value to a different ID, he could just log in as someone else... :s
    – Polynomial
    Commented Jan 12, 2013 at 13:14
  • 5
    @George Of course they can. Httponly just stops the cookies being accessed by JavaScript - any cookie editing addon for a browser will let the user change the cookie.
    – Polynomial
    Commented Jan 17, 2013 at 20:52
4

one of my colleges wants to generate the token by encrypting the current sign-in user's id concatenating a timestamps with a safely kept password. And then append the token into the form.

That's fine and a commonly-used approach where sessions are not available. But use a standard MAC for this (eg HMAC-SHA256) instead of your own single-layer concatenated-hash.

Another consideration is key lifecycle management: are you planning to change the server secret every so often? Do you have a mechanism to provide for a smooth changeover when you do (or when you are retiring the secret after a compromise)? Or is it OK to break everyone's old tokens in that scenario?

It sounds like you are using a similar signed-value scheme for the auth cookie. In that case you should consider (if you're not already) including a user password identifier as part of the cleartext/signed material, so that when the user changes their password it invalidates all previously-issued tokens. This could be a generation number, change-timestamp or storage salt.

There is also the implication that, because the datum you are matching for XSRF protection is the user ID, you are unable to protect the login form itself. Consider what would happen if an attacker used XSRF to cause a user to log in automatically to an account of the attacker's choice, maybe without the user noticing what account they're logged in as; does that potentially constitute a threat?

An approach that solves this if you need it is to add auth cookies for non-authenticated users, and include a secret in the auth cookie. Then include/sign that secret in the XSRF token: effectively the XSRF token is signing the auth cookie.

2

This is a valid approach in protecting against CSRF attacks. Some advantages over traditional methods include:

  • It’s not session-dependent
  • It doesn’t expose sub-domain vulnerabilities as per Double Submit

It’s called the Encrypted Token Pattern. Check this link for a full explanation and architectural overview. Also see the official OWASP description.

2
  • What about storing the CSRF token in local storage instead of the hidden field? im mostly asking because i would love to have a solution that works across page reloads. Commented Sep 15, 2015 at 18:36
  • Yes, there is no explicit requirement to store the Token in HTML mark-up. Storing the Token is session storage is perfectly acceptable. The point of the Encrypted Token Pattern is to offer flexibility, in terms of token-storage, on an application by application basis. Commented Sep 17, 2015 at 8:52

You must log in to answer this question.

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