Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it ok to use the (cryptographically strong) session cookie as CSRF token?

Reading OWASP CSRF prevention cheat sheet, one of the methods proposed to prevent these kind of attacks is the synchronizer token pattern.

If the session token is cryptographically strong, can it double as the csrf token as described in the following pseudocode?

Client:

<script>
dom.replace(placeholder, getCookie("session-cookie"))
</script>

<form>
<input type="hidden" name="csrf-cookie" value="placeholder-value"/>
<input type="text" />
</form>

Server:

if(request.getParameter("csrf-cookie") != user.getSessionCookie())
    print "get out you evil hacker"

The cookie is set with javascript on page load to prevent users from accidentally leaking the session cookie if they e.g. email a copy of the page to a friend.

like image 276
Erik Avatar asked May 21 '12 12:05

Erik


2 Answers

No, you shouldn't reuse the session token as your CSRF token. The OWASP CSRF prevention cheat sheet gives reasons why using the session identifier as a CSRF token is undesirable:

While this approach is effective in mitigating the risk of cross-site request forgery, including authenticated session identifiers in HTTP parameters may increase the overall risk of session hijacking. Architects and developers must ensure that no network appliances or custom application code or modules explicitly log or otherwise disclose HTTP POST parameters.

and

Inclusion of the session identifier within HTML can also be leveraged by cross-site scripting attacks to bypass HTTPOnly protections. Most modern browsers prevent client-side script from accessing HTTPOnly cookies. However, this protection is lost if HTTPOnly session identifiers are placed within HTML as client-side script can easily traverse and extract the identifier from the DOM. Developers are still encouraged to implement the synchronizer token pattern as described in this article.

Here are some more thoughts about why it might be not such a good idea to use the session id as the CSRF token. This article mentions packet sniffing on plain http connections and the ability to do man-in-the-middle attacks on them as potential risks.

Therefore it is essential that the CSRF token is a different one, otherwise the CSRF token would be trivially guessable if we assume the attacker already knows the session identifier! Put more defensively: It is probably not a good idea to play with fire: there's no need to re-use the session id as CSRF token, by doing so you only open another attack surface that could potentially be exploited. No reuse, no worries about that.

As a consequence, despite the session token being cryptographically secure, it additionally should be independent (also in the probabilistic sense) from the CSRF token for the whole thing to work under the above assumptions. That's also why any of the implementation examples always create their token from scratch.

You could use a cryptographically secure random number generator to create a sequence of bytes, hex- or Base64-encode them to obtain a string that is to be embedded in the page. OWASP recommends a length of 128 bits where they assume 64 bits of entropy (e.g. 8 random bytes transformed to a 16 byte hex string). The length of that sequence determines the level of security: guessing a 10 byte secure random number (which has 80 bits of entropy) succeeds with probability 2^(-80), which should suffice in most applications. So your final token should have a length of 20 bytes, a 10 byte random number transformed to hex encoding.

like image 105
emboss Avatar answered Oct 11 '22 02:10

emboss


Anything that cannot be retrieved by an external site can be used as a CSRF token. So contents of the session cookie is fine for this.

like image 20
ThiefMaster Avatar answered Oct 11 '22 00:10

ThiefMaster