Why are two CSRF tokens (hidden field and cookie) necessary to mitigate CSRF attacks?

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.

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.