I’ve watched the Pluralsight course on web security, which states that to mitigate CSRF attacks, the website should return two “paired” CSRF tokens to the client, one in a hidden form field and another in a cookie, that are associated to the user’s session. These tokens are issued whenever the user visits a page with, e.g., a form.

Now, since the attacker’s website can’t get the hidden form field token (same-origin policy), it cannot issue a valid request to the page containing the form.

But why are two CSRF tokens necessary in order to prevent CSRF? Isn’t the form field token sufficient by itself?

  • 1
    Yes, the cookie is not strictly necessary, as long as you have access to the original value somewhere. Putting it in an HTTP Only cookie provides an easy (stateless) way to track that, but if you have the value stored in the session or something like that, you don't need the cookie.
    – Joe
    Mar 15, 2018 at 17:46
  • What do you imagine that the form field token is being compared against for correctness? Mar 15, 2018 at 17:54
  • @EricLippert - The reason for two tokens is that they are compared for correctness? The server doesn’t store tokens? Otherwise one token would be enough... The reason it doesn’t store tokens is to move token storage completely to the client? How are the tokens linked to a particular user? And is there any reason for not using two form fields instead of a form field and a cookie?
    – Shuzheng
    Mar 15, 2018 at 18:02
  • If you used two equivalent form fields, you lose any advantage because the attacker could just make up values. The point of the token being stored server-side or in a cookie is that the attacker CANNOT read either of those things. They can send the cookie but they can't read it to populate the form field's value. Mar 11, 2022 at 21:44

3 Answers 3


The pattern you are describing is known as "double submit cookie", and it is a common way to defend against CSRF. The point here is that it doesn't require the server to remember the token. The client sends the token in both a cookie and some other way, e.g. in a form field. The server checks that both tokens are identical.

This works because the attacker can not read or write the cookie, and hence can't reproduce it in the form field. That is why it has to be sent twice:

  • If there was only a cookie, it would be sent automatically on every request and provide no protection at all.
  • If there was only a form field, there would be nothing to compare it to and the attacker could just enter any value.

There are other defences against CSRF, that only use one token. The most common is to just store the correct value in a session variable on the server, and check that a form field matches it. No cookie is needed. However, this has the drawback that the server has to maintain a per user state.

  • 2
    In the course, the tokens in the form field and cookie are not identical, but paired using strong cryptography.
    – Shuzheng
    Mar 15, 2018 at 19:38
  • @Shuzheng I don't know what benefit the crypto gives, but it sounds like the basic idea is the same - check that the two tokens "match".
    – Anders
    Mar 15, 2018 at 23:26
  • Why is “double submit cookie” good? I mean, the server must link the issued tokens to the particular user, so some session state is needed? If not, then tokens could be used several times to post a form. Or the attacker could himself get a valid pair of tokens and use these to forge requests on behalf of the user.
    – Shuzheng
    Mar 16, 2018 at 8:53
  • @Shuzheng No, there is no server state. The tokens just have to match each other. They do not have to match anything on the server. The tokens are not per request, so they can be reused. But an attacker can not forge a request since she can not read or write the value of the cookie.
    – Anders
    Mar 16, 2018 at 9:06
  • Would the server issue new tokens on each request then? Your point is that the cookie is HTTP-only, so it cannot be read/write by JS?
    – Shuzheng
    Mar 16, 2018 at 10:42

One token is enough provided it is the hidden form field, and is per request (meaning you receive a token in every response to be sent in next request). Please note that the token should not be stored in a cookie since cookies are sent automatically.

There are different ways to do things (and some are framework specific). The two token process also serves as a good way to solve the CSRF problem. The token in the cookie and on the page are cryptographically linked. So the server has to do this check and proceed with processing this request if everything is good.

  • If the client and server communicate over HTTPS, is it then necessary to issue a new token in every response? I mean, the attacker has no way of knowing the hidden form token received in the initial request? I’m just curious.
    – Shuzheng
    Mar 16, 2018 at 7:26
  • Yes it is necessary.The attacker can have multiple ways example a cross site scripting vulnerability can lead to compromise of the token. Applications have vulnerabilities that can compromise these tokens. Being on HTTPS does not solve every problem.
    – H4X
    Mar 16, 2018 at 17:13

To prevent CSRF attacks, the CSRF token must be matched against the expected token.

The website needs to store that expected token, and a common way to do that is by setting a cookie.

If both tokens match, then the form is valid.

  • Yes, but why are one token not enough?
    – Shuzheng
    Mar 15, 2018 at 17:48
  • Because you can't match your token against anything if there's only one token. Mar 15, 2018 at 17:49
  • Ahh - so the server doesn’t store the tokens itself? - It moves the storage completely to the client instead? If the server stored the tokens, then one token would be enough. But if the server doesn’t store the tokens, how does it link tokens to a particular user?
    – Shuzheng
    Mar 15, 2018 at 17:58
  • If the server stored the token (in a database / session for example), then one token would be enough indeed. Mar 16, 2018 at 8:23

You must log in to answer this question.

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