1

Is it safe to use one CSRF token per form on my page, ex:

<form>
    <input type="hidden" name="token" vale="<?=$data['login_token'];?>" />"
</form>
<form>
    <input type="hidden" name="token" vale="<?=$data['register_token'];?>" />"
</form>

Or should I just use one generic token for every form, ex:

<form>
    <input type="hidden" name="token" vale="<?=$data['token'];?>" />"
</form>
<form>
    <input type="hidden" name="token" vale="<?=$data['token'];?>" />"
</form>

Note that I will refresh the token on each page request.

Anders
  • 64,406
  • 24
  • 178
  • 215
MisterQuacker
  • 13
  • 1
  • 3
  • Why are you generating more than one form per page? – Robert Mennell May 09 '16 at 19:11
  • A third option: Use one per session, without chaning it on every page load. I don't see why that would be less secure, but there might be something I am missing. – Anders May 09 '16 at 19:34
  • Related: http://security.stackexchange.com/questions/26390/is-one-csrf-token-per-session-is-adequate-with-https – Anders May 09 '16 at 19:38
  • 2
    @RobertMennell should I not be? say I have the profile page for a user and have a change password field and a update status field. wouldn't I want one form to point to a page that deals with changing the password and another form to deal with updating statuses? Idk though I'm still learning this wonderful world of programming :) – MisterQuacker May 09 '16 at 19:43
  • 1
    Possible duplicate of [Why refresh CSRF token per form request?](http://security.stackexchange.com/questions/22903/why-refresh-csrf-token-per-form-request) – SilverlightFox May 10 '16 at 09:13
  • @SilverlightFox I think the per form, not per request, is a meaningful distinction here. – Anders May 10 '16 at 10:39

2 Answers2

4

As this question mentions, a single random unguessable token per session is sufficient.

When you start generating tokens per-page or per-form, you're simply limiting the impact of a CSRF token being leaked. Singular token leakage cases are relatively rare bugs, but XSS is obviously a common vector.

In certain cases it does indeed make sense to have a per-page or per-form CSRF token, as when combined with other protection features (e.g. disabling Ajax with CSP's connect-src directive) you can limit an XSS bug's ability to compromise CSRF tokens to the page which the XSS occurred, assuming you ensure that the token can't be re-used elsewhere.

Some people promote per-page or per-form CSRF protection as a way to increase security when using a double-submit cookie method, but I don't think this is sensible: if you have a bug that lets you read a cookie, you'd just read the session ID.

The flipside of the argument is that by implementing the more granular CSRF protection, you add additional complexity to your code, and that increases the attack surface and potential for bugs.

Personally, I'd stick with a single token per session, then implement other anti-automation controls (e.g. captcha, password re-entry) on top of this when needed for additional security.

Polynomial
  • 132,208
  • 43
  • 298
  • 379
0

Consider what you're protecting against: an attacker tricking a user into making a request they don't think they're making. How would multiple different tokens on the page protect against that any more than a single one?

Xiong Chiamiov
  • 9,384
  • 2
  • 34
  • 76