Known fact: Your website has be able to work without JavaScript.
–
HamZaMay 14 '13 at 8:37

6

So what? I'll just make Javascript mandatory
–
ManRowMay 14 '13 at 8:40

1

Well whatever, this will not protect you from CSRF IMO. CSRF is about an attacker sending a link to a user tricking him to do something, so I don't see how this will stop it ?
–
HamZaMay 14 '13 at 8:41

2

@HamZaDzCyberDeV If a user running IE 3 hits any site i've created they'll promptly be told to go back to sleep.
–
NULLZMay 14 '13 at 9:07

5 Answers
5

No because you should never allow scripts to be able to access your cookies. Refer to HTTPOnly on the OWASP website.

To prevent people from being able to steal session id's, should XSS be present, you should always set this cookie flag. Your mechanism would not work anymore as it would not be able to access the cookie.

And what if the site doesn't have any inherent XSS vulnerabilities?
–
ManRowMay 14 '13 at 8:53

4

@ManRow, that is a dangerous assumption to make. Making security tokens available to user-land code should generally be avoided, unless one is completely comfortable with the consequences of doing so. It would only take one XSS vulnerability to allow an attacker to extract the token and have his way with it.
–
ChristofferMay 14 '13 at 8:57

1

Security doesn't work with "What if this is taken out of the equation". You either go for a good approach or you just don't.
–
Lucas KauffmanMay 14 '13 at 8:58

Double submitting cookies is defined as sending the session ID cookie in two different ways for every form request. First as a traditional header value, and again as a hidden form value. When a user visits a site, the site should generate a (cryptographically strong) pseudorandom value and set it as a cookie on the user's machine. This is typically referred to as the session ID. The site should require every form submission to include this pseudorandom value as a hidden form value and also as a cookie value. When a POST request is sent to the site, the request should only be considered valid if the form value and the cookie value are the same. When an attacker submits a form on behalf of a user, he can only modify the values of the form. An attacker cannot read any data sent from the server or modify cookie values, per the same-origin policy. This means that while an attacker can send any value he wants with the form, the attacker will be unable to modify or read the value stored in the cookie. Since the cookie value and the form value must be the same, the attacker will be unable to successfully submit a form unless he is able to guess the session ID value.

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. An attacker that is able to obtain access to repositories or channels that leak HTTP POST parameters will be able to replay the tokens and perform session hijacking attacks. Note, however, that transparently logging all HTTP POST parameters is a rare occurrence across network systems and web applications as doing so will expose significant sensitive data aside from session identifiers including passwords, credit card numbers, and or social security numbers. 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.

No real reason not to just use the built-in CSRF prevention mechanism, almost all serious frameworks have this now.

Two disadvantages with this approach: (1) An XSS vulnerability will now allow the attacker to also get your session id --- since it's now just another field in the DOM. (2) No cache-ability; setting this hidden field value requires the server to dynamically generate the HTML since the HttpOnly sessionid cookie values are inaccessible from javascript. While #1 still applies to my approach, at least my approach resolves #2.
–
ManRowMay 14 '13 at 22:07

Since this is the top-voted question for double submit cookies, interested users should look at this Blackhat video regarding hacks that relate to Facebook and Twitter integration youtube.com/watch?v=jauXjSY-9LA
–
LamonteCristoJul 28 '13 at 4:01

You could, but it seems a bit unwieldy to me. Any CSRF-prevention mechanism works like this:

Make the server only accept requests that satisfy some conditions

Ensure that the conditions are something that can't be forged

Write your HTML so that the requests it generates follow the conditions set by the server.

The tried-and-tested method is to use <input type=hidden> in the HTML fields that contains some anti-CSRF token. Your method works as well1, but using JS to intercept and inject POST requests sounds icky and unnecessary when the whole client-side logic can be contained in the HTML.

1 As TildalWave noted, puting sensitive data in non-httponly cookies and making the accessible to client side JS could be a problem if you have XSS vulnerabilities. Stick with the tried and tested method then.

@ManRow - Well, it could potentially be a problem, if this value is read by a XSS, collecting end user session IDs and later used to forge requests (CSRF), or hijack user sessions. The whole point in using httponly in cookie headers is to signal the client (browser) not to enable client side scripts access to these cookies (usually session cookies), so they're not exposed to XSS. By adding this session ID value to a form field, you're needlessly enabling access to it. It's just safer to assume you can't trust the client, and since there's no need to do it this way, I'd suggest not to.
–
TildalWaveMay 14 '13 at 10:47

1

@SébastienRenauld: If someone is sniffing the request, they can just take the session cookie and be done with it. Why attempt CSRF when you have something better?
–
ManishearthMay 14 '13 at 15:15

2

@SébastienRenauld: How would you "load up a form"? Same origin policy makes sure that you don't GET x-site forms.
–
ManishearthMay 14 '13 at 18:06

As mentioned by a number people - double submit is an ok CSRF protection, provided that you use a separate nonce. Using session id is very wrong in this context, starting with the fact that sessionid has to be HTTPOnly for XSS protection.

An argument of "what if there is XSS on this page/website" is not valid - when you have XSS, CSRF is the least of your worries. The browser becomes fully remotely controllable via an injected script and CSRF is not required to force the browser to do actions on behalf of the user.

Looks like the simple solution (i.e., CSRF protection but with all-cacheable web resources) is to just add a separate cookie containing the anti-CSRF token but accessible to page javascript.

In other words, when the client logs in, I'll actually set two cookies (one HttpOnly sessionid and one non-HttpOnly anti-CSRF token, accessed by page scripts). So, the server will store (along with a client sessionid) their anti-CSRF token value and validate that it's the same value as the one originally set via the second cookie. If validation fails, you have a potential CSRF.

And what would stop the 2nd cookie from being submitted by a CSRF attack, same as the session id cookie...?
–
AviD♦May 21 '13 at 6:51

Because the CSRF cookie is submitted twice: (#1) once as a regular cookie (just a regular cookie w/o CSRF protection), but ALSO (#2) as a property dynamically added (at the same time) via the page's javascript into the body of every request from that page. The server will validate that the anti-CSRF token value passed via mechanism #1 (standard cookie mechanism) is the same as the one sent (at the same time) via mechanism #2 (the value of which only your page's javascript can access); if it's not the same or missing, the server will suspect CSRF.
–
ManRowMay 21 '13 at 7:20

Of course, the anti-CSRF cookie value will just be overwritten/reset every time the user gets a new sessionid...
–
ManRowMay 21 '13 at 7:24

ah, I see - that was not clear from your answer. However, while this scheme could work fine (I dont see any issues with it offhand), it needlessly over-complicates things. Why try to build this (and you will probably get some parts wrong, like the cryptographic bits), when you have a perfectly fine mechanism built in to almost any framework or platform you're using?
–
AviD♦May 21 '13 at 7:43

Cache-ability: my entire site is now cache-able, since the server doesn't need to cook this token into the returned HTML each time. I can now just use all static HTML & JS files...
–
ManRowMay 22 '13 at 4:08