Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSRF token generation

Tags:

csrf

This is a question about generating CSRF tokens.

Usually I'd like to generate a token based off of a unique piece of data associated with the user's session, and hashed and salted with a secret key.

My question is in regards to generating tokens when there is NO unique user data to use. No sessions are available, cookies are not an option, IP address and things of that nature are not reliable.

Is there any reason why I cannot include the string to hash as part of the request as well? Example pseudocode to generate the token and embed it:

var $stringToHash = random() var $csrfToken = hash($stringToHash + $mySecretKey) <a href="http://foo.com?csrfToken={$csrfToken}&key={$stringToHash}">click me</a> 

Example server-side validation of the CSRF token

var $stringToHash = request.get('key') var $isValidToken = hash($stringToHash + $mySecrtKey) == request.get('csrfToken') 

The string being used in the hash would be different on each request. As long as it was included in each request, the CSRF token validation could proceed. Since it is new on each request and only embedded in the page, outside access to the token would not be available. Security of the token then falls to the $mySecretKey being known only to me.

Is this a naive approach? Am I missing some reason why this cannot work?

Thanks

like image 248
Jim Beam Avatar asked Nov 26 '09 21:11

Jim Beam


People also ask

How is a CSRF token generated?

A CSRF token is a unique, secret, unpredictable value that is generated by the server-side application and transmitted to the client in such a way that it is included in a subsequent HTTP request made by the client.

How is CSRF token generated in Java?

getSession(). getAttribute("CSRF_TOKEN_FOR_SESSION_NAME"); is called and is null. After this String rt = CSRFTokenManager. getTokenFromRequest(request); is called which generates and sets a new value to session attribute.

What is CSRF token and how it works?

A CSRF token is a secure random token (e.g., synchronizer token or challenge token) that is used to prevent CSRF attacks. The token needs to be unique per user session and should be of large random value to make it difficult to guess. A CSRF secure application assigns a unique CSRF token for every user session.


2 Answers

Is there any reason why I cannot include the string to hash as part of the request as well?

CSRF tokens have two parts. The token embedded in the form, and a corresponding token somewhere else, be it in a cookie, stored in a session or elsewhere. This use of elsewhere stops a page being self contained.

If you include the string to hash in the request, then the request is self contained, so copying the form is all an attacker needs to do, as they have both parts of the token, and thus there is no protection.

Even putting it in the form URL means that it's self contained, the attacker simply copies the form and the submission URL.

like image 85
blowdart Avatar answered Oct 14 '22 19:10

blowdart


Try base64_encode(openssl_random_pseudo_bytes(16)). https://github.com/codeguy/php-the-right-way/issues/272#issuecomment-18688498 and I used it for my form example in https://gist.github.com/mikaelz/5668195

like image 32
michalzuber Avatar answered Oct 14 '22 21:10

michalzuber