Monday, April 13. 2020
Generating CRIME safe CSRF Tokens
Trackbacks
Trackback specific URI for this entry
No Trackbacks
Comments
Display comments as
(Linear | Threaded)
Thanks for writing this up! I've been working on a little web app and wondering about whether the new SameSite header is enough to make CSRF tokens redundant.
You can use `hash_equals()` function to compare two hashes to provide time-attack safety.
I'm also working on a stateless CSRF project (https://github.com/Ayesh/StatelessCSRF) that can be used to generate CSRF tokens based on a server-stored secret, and with tokens bound to IP addresses, user-agent strings, etc.
I'm also working on a stateless CSRF project (https://github.com/Ayesh/StatelessCSRF) that can be used to generate CSRF tokens based on a server-stored secret, and with tokens bound to IP addresses, user-agent strings, etc.
hash_equals() sounds like a good improvement, done that now.
As Ayesh already mentioned, you should not rely on `==` (double-equals check) as it is vulnerable to type juggling attacks (see https://owasp.org/www-pdf-archive/PHPMagicTricks-TypeJuggling.pdf) and instead use `hash_equals` to mitigate timing side channel attacks.
Your generated CSRF tokens don't ever expire and old tokens remain valid. It would be quite trivial to find a valid token if timing information is accurate by sending different suffixes (updated from MSB to LSB) while the prefix remains static.
Your generated CSRF tokens don't ever expire and old tokens remain valid. It would be quite trivial to find a valid token if timing information is accurate by sending different suffixes (updated from MSB to LSB) while the prefix remains static.
The tokens expire with the session, which is outside the scope of this code to deal with how long they last.
I agree that safeguarding against timing is a good idea. But I am inclined to disagree that it "would be quite trivial" to perform a timing attack in any real world situation, but happy to be proven wrong here :-)
I agree that safeguarding against timing is a good idea. But I am inclined to disagree that it "would be quite trivial" to perform a timing attack in any real world situation, but happy to be proven wrong here :-)
Your CSRF tokens sound like they become closer to capabilities: tokens constrained to a specific resource/action. CSRF is a classic confused deputy so capabilities are a natural countermeasure.
I don’t like SameSite cookies because they are a very blunt instrument. Firstly, yes there are absolutely CSRF attacks that they don’t prevent: “site” means top-level registerable domain (eg example.com). This means that if somebody compromises wordpress.someforgottenproduct.example.com they can use that to launch CSRF attacks against payroll.example.com or whatever. SameSite will not prevent those because it’s considered the “same site”.
Secondly, there are legitimate reasons for wanting cross-origin cookies. For example, SameSite breaks several patterns in federation protocols like SAML and OIDC - eg when setting a state/nonce cookie and then using form_post response mode in OIDC. SAML Single-Logout with the HTTP POST binding is broken. And so on. If you ever use CORS with AC-Include-Credentials for genuine cross-site requests then that is also broken by SameSite. So people will probably disable SameSite cookies for these cases (until the browsers make it mandatory).
I don’t like SameSite cookies because they are a very blunt instrument. Firstly, yes there are absolutely CSRF attacks that they don’t prevent: “site” means top-level registerable domain (eg example.com). This means that if somebody compromises wordpress.someforgottenproduct.example.com they can use that to launch CSRF attacks against payroll.example.com or whatever. SameSite will not prevent those because it’s considered the “same site”.
Secondly, there are legitimate reasons for wanting cross-origin cookies. For example, SameSite breaks several patterns in federation protocols like SAML and OIDC - eg when setting a state/nonce cookie and then using form_post response mode in OIDC. SAML Single-Logout with the HTTP POST binding is broken. And so on. If you ever use CORS with AC-Include-Credentials for genuine cross-site requests then that is also broken by SameSite. So people will probably disable SameSite cookies for these cases (until the browsers make it mandatory).
I hope you don't mind, I'd like to add a link to this blog and discussion to Chapter 4 of my book (API Security in Action, Manning), which covers cookies and CSRF. I think this is a really nice addition to the usual CSRF defences.
Sure, feel free. If you want you can add the blogpost in full :-)
(The texts on this blog are CC0 licensed.)
(The texts on this blog are CC0 licensed.)