True Stories of the TRC-Web Application Security

Flash + 307 Redirect = Game Over

A vulnerability for Ruby on Rails was recently patched [http://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails].
Why the Patch Was Necessary
The default CSRF prevention built into RAILS has two components: (1) a custom HTTP Header, and (2) a CSRF token in the post body. The default was designed so that only one, rather than both, of the components was required in a request. Modern browser security typically makes this a fairly secure method, because JavaScript cannot create custom HTTP Headers and then have them sent across domains. However, a researcher from Google found a way to exploit this issue by using “certain combinations of browser plugins and HTTP redirects.” Because of this discovery, the new patch for Ruby on Rails now requires both components to be in the request, preventing exploitation.
How the Vulnerability Bypassed the Default CSRF Security
A hidden flash file on a website automatically sent the following request:
http://www.attacker.com/redirect.php?status=307&url=http://www.victim.com
Flash allowed the site where the file was running to specify POST data and additional headers. But before sending the request, Flash checked the site’s crossdomain.xml file. Attackers then set up their cross domain.xml files as follows:
http://www.attacker.com/crossdomain.xml
<?xml version=”1.0″ encoding=”UTF-8″?>
<cross-domain-policy>
<allow-access-from domain=”*”/>
<allow-http-request-headers-from domain=”*” headers=”*”/>
</cross-domain-policy>
Based on this, the Flash file understood that it then had permission to send additional header information with its request, and proceeded to send the request with extra headers to
[http://www.attacker.com/redirect.php?status=307&url=http://www.victim.com].
The attacker site returned a 307 redirect. The 307 is like a 302 redirect, but also allows the forwarding of POST data. The Flash application, realizing that the data was going to another Web server, attempted to retrieve the crossdomain.xml file for www.victim.com. Unfortunately, it appears that in certain circumstances, Flash will IGNORE the crossdomain.xml file for victim.com, and rely instead on the original crossdomain.xml file at www.attacker.com. After a confirmation message that would confuse most users, the Flash application sent a new request:
POST / HTTP/1.1
Host: www.victim.com
X-Header: test=data;
Cookie: abc=123
Content-Length: 9
post=body
We see here that the POST request was sent to www.victim.com, along with the additional headers and the POST body. This clearly illustrates that Web server frameworks can no longer rely solely on the implied security of additional HTTP Request Headers to prevent CSRF.
Breakdown of the Vulnerability
Mac – Flash Player 10,2,154,12Chrome 9.0.597.94 302 Redirect GET Request, with headers
Chrome 9.0.597.94 307 Redirect Not Sent
Safari 5.0.3 (6533.19.4) 302 Redirect GET Request, with headers
Safari 5.0.3 (6533.19.4) 307 Redirect POST Request, with headers (No Confirmation)
FireFox 3.6.10 302 Redirect GET Request, no headers
FireFox 3.6.10 307 Redirect POST Request, with headers
FireFox 4 beta 8 no bueno
Windows XP – Flash Player 10.2.152.26
FireFox 3.6.10 302 Redirect GET Request, no headers
FireFox 3.6.10 307 Redirect POST Request, with headers
IE 7 no bueno
IE 8 no bueno
Tags: security
  • http://hyiamn.blogspot.com/ Johnny

    Thanks for sharing this item. So if the trick is to somehow include additional http headers so it get pass to a vitcim site to bypass their CSRF control, it sounds like a non-flash method may be the following: a non-victim site that is vulnerable to XSS can include an iframe that points to the attacker’s page with server-side code that craft the http header and redirect to the victim site. Does this seem reasonable?

    • https://twitter.com/superevr Phil Purviance

      Johnny, that would be the ideal attack vector for this. However, the Same origin policy in browsers prevents JavaScript and most other client side code from sending requests with manipulated headers across domains. In this case, it appears that some browsers were not providing Flash the necessary information to make a good decision on whether it should send this request or not, bypassing the same origin policy.

      “… origins can use custom HTTP headers when sending requests to themselves but cannot use custom headers when sending requests to other origins.”

      Reference: http://www.w3.org/Security/wiki/Same_Origin_Policy

  • Michael Alford

    Has this vulnerability since been fixed in modern browsers? I know it was fixed in Firefox 3.5.17 and Firefox 3.6.14, but I cannot find any information when/if it was fixed on other browsers such as Internet Explorer, Chrome, or Safari.

  • Ons Ali

    I’m wondering, is this still exploitable?