I have a little problem regarding to my CSRF token function (it changes the token every request). Here is the scenario of my problem:

When I opened 2 pages (with same CSRF Token), when I open the first page and submit the form there, the second page's form is not working(because the CSRF Token's value is changed). If you view it from the user's experience it will leave a bad taste, so I need to change it.

My question is, how can I make my CSRF Token function, works in multi-tab browsing, while not affecting the security along with better user experience? Because I want them to have a better user experience without affecting the security of their browsing.

  • 2
    Possible duplicate of Why refresh CSRF token per form request? Sep 16, 2016 at 7:34
  • 2
    I would recommend just using one CSRF token per user instead. I have so far not heard any argument against that that I find compelling.
    – Anders
    Sep 16, 2016 at 7:57
  • @SilverlightFox I read that, and the conclusion that I made after reading that is to remove all the tokens in my forms, except in login and signup forms? I can not comment to that thread that is why I made I post here.
    – googol8080
    Sep 16, 2016 at 11:53
  • If that is the case I would suggest you link to that question in your post and explain why that answer doesn't fit with your situation. Click edit to do this. The accepted answer was explaining to issue new tokens at the point of login, but not to remove them elsewhere. Sep 16, 2016 at 12:46
  • 1
    Use session CSRF tokens Sep 16, 2016 at 17:08

2 Answers 2


Use a single CSRF token per session (rather than per request or per user). For example, the CSRF token can be the plain text session ID, or an encrypted or securely hashed (e.g. HMAC) version of the session key. Or you could store the CSRF token as a session variable that is associated with the session key. These are all common options.

If you're wondering if this makes your site any less secure, read this article for reassurance.

If you happen to be using the ASP.NET framework, the way to do this is simply set the Page.ViewStateUserKey to the session ID.

  • What if an attacker get the csrf token? what will I do ?
    – googol8080
    Sep 19, 2016 at 12:20
  • A typical CSRF mitigation assumes that the attacked cannot obtain the CSRF token. If you are concerned about how to guard the token, please start another question.
    – John Wu
    Sep 19, 2016 at 17:07
  • 2
    Don't use the session ID as the CSRF token, ever. It's a lot more likely that a CSRF token will leak than that a session ID (properly protected) will leak, and increasing the ways a session token could be leaked is a very bad idea. HMACing the session token with a server-side secret is pretty safe (using a completely random CSRF token is better but requires storing additional per-session state).
    – CBHacking
    Mar 22, 2017 at 18:16

We need more details. Are you using a framework?

Furthermore, if you are creating a token for each request, how come two tabs have the same one? It kinda contradicts what you said.

Or maybe I misunderstood and you mean that you have only ONE csrf token "active" at a time. In that case the fix would be easy, allow for multiple CSRF tokens to be valid at the same time (by holding a list of sent ones server side). That way two different tabs have two different tokens, both of which are valid.

  • Hello, thanks for your response, how can I make a list? What do I need?
    – googol8080
    Sep 16, 2016 at 7:26
  • Again, this would depend on the technology/framework you are using. Since you are faced with this issue I am guessing you are not using a webapp framework like Django or Rails, as they would take care of this issue. In PHP i would hold the pending tokens in a table together with an expiration date. Every time you get a POST request, you check in that table, if you find the token and it is not expired, you process the request. Otherwise you reject it. I would also make sure that expired tokens get purged once in a while. But I would suggest you use an existing framework!
    – daniel f.
    Sep 16, 2016 at 7:35
  • 4
    This is mostly a request for more information and not an answer. Please put this in a comment. Sep 16, 2016 at 7:40
  • I was torn, but as the "answer part" was longer than the request for more information I opted for an answer.
    – daniel f.
    Sep 16, 2016 at 7:43
  • then split this up as comments and an answer
    – schroeder
    Sep 16, 2016 at 8:08

You must log in to answer this question.

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