views:

284

answers:

3

I've read several XSRF solutions that rely on adding more tokens to the response, which do help protect code that only runs on POST.

i.e. this would be a one step attack relying on a page that responds to HTTP GET

<img src="http://amazon.com/buybook/anarchistscookbook/mailto/me/execute.php"&gt;

But with better libraries like jquery, its getting easier to write malicious javascript XmlHttpRequest scripts, that can do a two step attack (a GET, parse the Anti-XSRF viewstate/query string/extra cookie etc) and then submit a POST. (Or is it? I don't worry about AES being cracked any time soon, should I even worry about 2 step XSRF attacks targeting HTTP POST actions becoming as easy as the img tag attack shown above?)

I suppose the one step attack can mostly be tharted by not doing anything sensive on GET, could both kinds of attacks be tharted by requiring the website user to solve a CAPTCHA, which then yeilds a query string token that would be required for all URLs for the rest of the session?

So far it seems like it would only fail when CAPTCHA fails, such as if OCR software can read the text or if there is a mechanical turk component.

EDIT: The particular attack in mind is an email with xhr javascript or image tag. So the code would be executing in email client's browser or from a HTML page loaded from the local filesystem. For simplicities sake, I'm imagining the site has no XSS vulnerabilties (ie. no opportunities for malicious users to inject their HTML into the HTML the site sends as responses)

+1  A: 

The point is that JavaScript can't read the anti-XSRF token from a cross-domain context, and XMLHTTPRequest is same-origin only, so it cannot be used to steal the token.

If your site already has a XSS vulnerability, you're already hosed, and anti-XSRF tokens won't help you.

EricLaw -MSFT-
Hmm, interesting. Your referring to HTTPOnly double submitted cookies, right?About XSS, true, but you don't need XSS to pull off a XSRF? The classic example is a email with either JavaScript for POSTs or an image tag for GETs.
MatthewMartin
If a site doesn't attempt to mitigate XSRF at all, then yes, a bad guy won't need XSS to exploit it.The typical defense against XSRF is to use a one-time token, either in a form, or cookie. This defense is generally void if the site in question has an XSS vulnerability.
EricLaw -MSFT-
+1  A: 

Neither XmlHttpRequests nor javascript frame manipulation work cross-domain these days; that would be sheer insanity. CSRF attacks these days usually consist of either the image tag like you mentioned or autogenerating a form that POSTs to another site. However, retrieving an anti-XSRF token (presumably a cryptographic nonce generated on a per-session basis) is next to impossible. Only if it's an exceedingly poor token that doesn't check the user session and IP address could a server-side language possibly be leveraged to retrieve it and then combine it with a client-side CSRF. Aside from tokens, plenty of people stop CSRF simply by checking the referrers and blocking all remote domains. Submitting CSRF with XmlHttpRequests is virtually impossible thanks to domain restrictions.

At any rate, you don't have to worry about XmlHttpRequest being able to access a remote domain. The only time something like that could happen is if you have a XSS vulnerability, in which case, as EricLaw said, you're already hosed.

Coding With Style
If the page is loaded from the local file system (say as the result of a malicous email), then xhr seems to be able to make posts to sites which the user is logged on to. I'm not clear on how the cross domain rules affect JS running on the local file system.
MatthewMartin
As far as I can tell those tricks have been blocked for a while now. Moreover, if you're discussing your users downloading and running trojan horses, you really can't defend your site from that.
Coding With Style
+1  A: 

I think you are confused about the same-origin policy. Requesting a html page that is in a local file does not circumvent this policy. In fact, i beleive even more strict rules apply to a file resource. You will find that Javascript in a local html file will not be able to make a succesful request to retreive a non-local resource.

Modern browsers do not allow Javascript in local HTML files access to remote HTTP resources.

In which browser have you been able to succesfully perform a cross-domain XHR from a file:/// resource?

I have tested this in ie6, ie7, ie8, firefox 3, firefox 3.5 and recent versions of chrome, opera, and safari on windows; they all reject the cross-domain http request.

<html>
<head>
<script 
  type="text/javascript" 
  src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"&gt;&lt;/script&gt;
<script type="text/javascript">
  $(document).ready(function() {
    $( '#xhr' ).append( 'replace me with remote xhr' );
    $( '#xhr' ).load( 'http://stackoverflow.com/', function() {
      $( '#xhr' ).append( 'xhr load complete' );        
    });
  });
</script>
</head>
<body>
  test
  <div id="xhr">original</div>
</body>
</html>

It is possible that some much older browsers are less restrictive.

Cheekysoft
Less "possible" and more "known fact." Before greasemonkey existed, I wrote pages that embedded remote sites in frames and modified them with javascript.
Coding With Style