Alright here is my proposal:
Use a hash of a login token as the anti-CSRF token.
Why this is a good idea?
- Prevents having to store anything extra on the client, the server, and less network traffic as we don't need to transfer an additional cookie on every request
- All the benefits of cookie based CSRF token
- Login token still can't be accessed by JS (Its a non-reversible hash so we output the hashed login cookie in a meta tag, AJAX can still use it without exposing the login token
- If login token is indeed unique per session (even between the same users) then each csrf token will be unique per session (minus collisions)
Is there any security problems I am missing? Obviously this would only work for pages where the user is logged in. But that shouldn't be an issue.
Btw by "login token", I mean a securely pseudorandom string that is stored on the server and on the client in the form of a cookie that allows the server to authenticate a user without them having to enter their password each time the page changes.
Ok so it was brought up that by using this method you are decreasing security ever so slightly because the hash is based off of the login token and you could brute force to find the login token. Even tho I think this is basically impossible because of how hashes work I propose the following solution. Split the login token into 4 parts, hash the 3rd and 4th using the 2nd as a salt. This prevent the use of rainbow tables and even if an attacker somehow brute forces, they will only have 3/4th of login token. Also, the salt doesnt need to be prepended to the csrf token itself because it can be derived using the login token.
SHA3-512
a la npmjs.com/package/sha3 would be my suggestion for algorithm @JBis