anti-CSRF token and Javascript
Asked Answered
C

1

32

I'm trying to protect an application (php and lots of JS) from CSRF.

I want to use tokens.

A lot of operations are done with AJAX, so I have to pass the token in Javascript. If I want to generate 1 token per session or per page load it's simple - I generate new token, put it somewhere in a DOM and then find it with Javascript and send to the processing side.

But what if I want to use new token for every operation? I was thinking about doing an ajax call to regenerate token and then pass the result to processing page.

Does this increase security risk? I was thinking about luring user to page with script which would ask for token and then use it to make the request but then again cross domain Javascript is forbidden. Can it be done with flash?

Maybe another approach for protecting ajax calls from CSRF?

Thanks!

Cardwell answered 8/9, 2010 at 1:33 Comment(1)
Answer to same question: #33574843 says AJAX is allowed for getting CSRF tokensDirector
D
30

There are several techniques, which when used together provide a sufficient CSRF protection.

Unique Token

A single, session-specific token is good enough for most applications. Just make sure that your site doesn't have any XSS vulnerabilities, otherwise any kind of token technique you employ is a waste.

AJAX call to regenerate the token is a bad idea. Who will guard the guards? If the AJAX call itself is vulnerable to CSRF, it kind of defeats the purpose. Multiple tokens with AJAX are in general bad idea. It forces you to serialize your requests i.e. only one AJAX request is allowed at a time. If you are willing to live with that limitation, you can perhaps piggyback token for the second AJAX call in response to the first request.

Personally, I think it is better to re-authenticate the user for critical transactions, and protect the remaining transactions with the session-specific token.

Custom HTTP header

You can add a custom HTTP header to each of your requests, and check its presence on the server side. The actual key/value doesn't need to be secret, the server just needs to ensure it exists in the incoming request.

This approach is good enough to protect CSRF in newer versions of the browsers, however its possible too work-around this if your user has older version for Flash Player.

Checking Referrer

Checking for the Referrer header is also good to protect CSRF in the newer browsers. Its not possible to spoof this header, though it was possible in older versions of Flash. So, while it is not foolproof, it still adds some protection.

Solving Captcha

Forcing the user to solve a captcha is also effective against CSRF. Its inconvenient as hell, but pretty effective. This is perhaps the only CSRF protection that works even if you have XSS vulnerabilities.

Summary

  1. Use a session based token, but re-authenticate for high value transactions
  2. Add a custom http header, and also check for referrer. Both are not foolproof by themselves, but don't hurt
Doane answered 8/9, 2010 at 6:27 Comment(5)
Adding a custom http header bothers me, I'm pretty sure you can forge custom http headers with flash and fire off a request to another server, as long as the header element isn't on a blacklist. I have looked at the recent changes to flash (within the past 3 months) and they fixed the ability control the entire POST segment which was needed for "cross site file upload" attacks. Other than that i think its good info and i gave you a +1.Bulbil
Yeah, here is the blacklist, of course referer isn't allowed, but literally everything else is. kb2.adobe.com/cps/403/kb403030.htmlBulbil
@The Rook - Re. Adding custom headers - See adobe.com/devnet/flashplayer/articles/…. Specifically, see the section titled "Header Sending Permissions". I quote When a SWF file wishes to send custom HTTP headers anywhere other than its own host of origin, there must be a policy file on the HTTP server to which the request is being sent. Remember #2610334? That's where I learned this fact the hard way..Doane
@SripathiKrishnan : In many answers on this site it is mentioned that a token should be supplied in a hidden field along with a cookie. If the values of both of them don't match, then it is a possible CSRF heck. I know, it is because of the same origin policy, the attackers cannot just read or modify the cookies on the victim's browser. In addition to this check, is it necessary to see, if this token value matches the one stored in the session? It is nowhere mentioned. It shouldn't be crucial but I'm unsure about it.Unvoiced
@SripathiKrishnan Why AJAX call is vulnerable to CSRF?Director

© 2022 - 2024 — McMap. All rights reserved.