A vulnerability for Ruby on Rails was recently patched [http://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails].
The default CSRF prevention built into RAILS had two components: (1) a custom HTTP Header, and (2) a CSRF token in the post body. This was implemented in a way that only one of these components were required in a request, and not both. Modern browser security makes this fairly secure because JavaScript cannot create custom HTTP Headers and have them sent across domains. However, a researcher from Google found that there is a way to exploit this issue using "certain combinations of browser plugins and HTTP redirects". The new patch for Ruby on Rails forces both of these components to be in the request, preventing exploitation.
A hidden flash file on a website will automate the sending of the following request:
http://www.attacker.com/redirect.php?status=307&url=http://www.victim.com
Flash will allow the site which it is running from to specify POST data and additional headers. But before sending the request, it will check the sites crossdomain.xml file. The attacker will set up their cross domain.xml file as follows.
http://www.attacker.com/crossdomain.xml
The flash file will understand that it now has permission to send additional header information with its request, and will proceed with sending the request with extra headers to
[http://www.attacker.com/redirect.php?status=307&url=http://www.victim.com]
The attacker site will return a 307 redirect. It's like a 302 redirect, but allows the forwarding of POST data too. The flash application will realize that it is going to another web server, and will attempt to retrieve the crossdomain.xml file for www.victim.com. Unfortunately, it appears that it certain circumstances, Flash will IGNORE the crossdomain.xml file for victim.com, and instead rely on the original crossdomain.xml file at www.attacker.com. After a confirmation message that will be unclear to most users, the flash application sends a new request.
POST / HTTP/1.1
Host: www.victim.com
…
X-Header: test=data;
Cookie: abc=123
Content-Length: 9
We see here that the POST request is being set to www.victim.com, with the additional headers and the POST body. Web server frameworks can no longer rely on the implied security of additional HTTP Request Headers alone to prevent CSRF.
Breakdown of the vulnerability:
Mac - Flash Player 10,2,154,12
Chrome 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
Testing the vulnerability yourself:
We see here that the POST request is being set to www.victim.com, with the additional headers and the POST body. Web server frameworks can no longer rely on the implied security of additional HTTP Request Headers alone to prevent CSRF.
I think it would be more reasonable to convince Adobe to fix it, than
to write off this mechanism as an XSRF defense... unfortunately, as I
understand it, they are aware of this problem for a longer while (> 6
months), and it's been quasi-public ever since...
/mz
Thanks for sharing this. I assumed it would be flash because RoR team made a
backward incompatible change to their library to fix this issue.
Michal - I agree Flash should fix this. What's their justification for not
doing so?
--Sri
On 11 February 2011 01:41, Michal Zalewski lcamtuf@coredump.cx wrote:
We see here that the POST request is being set to www.victim.com, with
the additional headers and the POST body. Web server frameworks can no
longer rely on the implied security of additional HTTP Request Headers alone
to prevent CSRF.
I think it would be more reasonable to convince Adobe to fix it, than
to write off this mechanism as an XSRF defense... unfortunately, as I
understand it, they are aware of this problem for a longer while (> 6
months), and it's been quasi-public ever since...
/mz
The Web Security Mailing List
WebSecurity RSS Feed
http://www.webappsec.org/rss/websecurity.rss
Join WASC on LinkedIn http://www.linkedin.com/e/gis/83336/4B20E4374DBA
WASC on Twitter
http://twitter.com/wascupdates
websecurity@lists.webappsec.org
http://lists.webappsec.org/mailman/listinfo/websecurity_lists.webappsec.org
On Thu, Feb 10, 2011 at 12:11 PM, Michal Zalewski lcamtuf@coredump.cx wrote:
We see here that the POST request is being set to www.victim.com, with the additional headers and the POST body. Web server frameworks can no longer rely on the implied security of additional HTTP Request Headers alone to prevent CSRF.
I think it would be more reasonable to convince Adobe to fix it, than
to write off this mechanism as an XSRF defense... unfortunately, as I
understand it, they are aware of this problem for a longer while (> 6
months), and it's been quasi-public ever since...
Out of curiosity (and willing to confess my ignorance) is there a spec
somewhere that explains the "proper" behavior, is Adobe not following
that spec, and if not specified somewhere, where should this be?
Seems that every time a security defense gets created that relies on
certain aspects of browser behavior especially as it relates to
headers that are or are not sacrosanct, we end up with these sorts of
problems... Obviously room for improvement.
Out of curiosity (and willing to confess my ignorance) is there a spec
somewhere that explains the "proper" behavior, is Adobe not following
that spec, and if not specified somewhere, where should this be?
As with much of the web, there isn't one (and if there was, it would
probably have nothing to do with reality).
That said, it is commonly understood, and enforced by most places
(e.g., XMLHttpRequest), that websites should not be able to make
cross-domain requests with arbitrary HTTP headers without some sort of
a mutual consent (e.g., CORS). There is every indication to suggest
that Flash tried to enforce it, too (you need a crossdomain.xml rule);
but is duped by a 307 redirect.
To put this in perspective, there is also no top-level spec explicitly
saying that a.com should not be able to read the contents of b.com.
/mz
Out of curiosity (and willing to confess my ignorance) is there a spec
somewhere that explains the "proper" behavior, is Adobe not following
that spec, and if not specified somewhere, where should this be?
As with much of the web, there isn't one (and if there was, it would
probably have nothing to do with reality).
Technically the HTTP RFC specifies the behavior for the 307 code and this is following
that specification. The issue is flash's model requires crossdomain.xml approval
prior to issuing requests, and in this case is tricked by the 307, and doesn't fetch
a crossdomain.xml on the new domain.
There are two fixes, one for Flash, and one for Ror (which they've implemented).
The correct flash fix would be to fetch the crossdomain.xml file on the 307'd domain
(or any 3xx code) and seek approval prior to making a request.
Regards,
I'd just like to clarify (for the lulz), that Adobe have been aware of
this since May 2008.
However if it no longer works on IE, it means that some progress is
being made, because from what I heard the issue for Adobe was that
none of the browsers gave them enough control to be able to stop this.
On 11 February 2011 07:11, Michal Zalewski lcamtuf@coredump.cx wrote:
We see here that the POST request is being set to www.victim.com, with the additional headers and the POST body. Web server frameworks can no longer rely on the implied security of additional HTTP Request Headers alone to prevent CSRF.
I think it would be more reasonable to convince Adobe to fix it, than
to write off this mechanism as an XSRF defense... unfortunately, as I
understand it, they are aware of this problem for a longer while (> 6
months), and it's been quasi-public ever since...
/mz
The Web Security Mailing List
WebSecurity RSS Feed
http://www.webappsec.org/rss/websecurity.rss
Join WASC on LinkedIn http://www.linkedin.com/e/gis/83336/4B20E4374DBA
WASC on Twitter
http://twitter.com/wascupdates
websecurity@lists.webappsec.org
http://lists.webappsec.org/mailman/listinfo/websecurity_lists.webappsec.org
FWIW, this vulnerability has been addressed in the latest version of
Firefox.
http://www.mozilla.org/security/announce/2011/mfsa2011-10.html
On Tue, Feb 22, 2011 at 5:16 PM, kuza55 kuza55@gmail.com wrote:
I'd just like to clarify (for the lulz), that Adobe have been aware of
this since May 2008.
However if it no longer works on IE, it means that some progress is
being made, because from what I heard the issue for Adobe was that
none of the browsers gave them enough control to be able to stop this.
On 11 February 2011 07:11, Michal Zalewski lcamtuf@coredump.cx wrote:
We see here that the POST request is being set to www.victim.com, with
the additional headers and the POST body. Web server frameworks can no
longer rely on the implied security of additional HTTP Request Headers alone
to prevent CSRF.
I think it would be more reasonable to convince Adobe to fix it, than
to write off this mechanism as an XSRF defense... unfortunately, as I
understand it, they are aware of this problem for a longer while (> 6
months), and it's been quasi-public ever since...
/mz
========== original post ==========
From: Phillip Purviance phillip.purviance@whitehatsec.com
Date: Thu, Feb 10, 2011 at 1:22 PM
Subject: [WEB SECURITY] CSRF: Flash + 307 redirect = Game Over
To: "websecurity@lists.webappsec.org" websecurity@lists.webappsec.org
A vulnerability for Ruby on Rails was recently patched [
http://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails
].
The default CSRF prevention built into RAILS had two components: (1) a
custom HTTP Header, and (2) a CSRF token in the post body. This was
implemented in a way that only one of these components were required in a
request, and not both. Modern browser security makes this fairly secure
because JavaScript cannot create custom HTTP Headers and have them sent
across domains. However, a researcher from Google found that there is a way
to exploit this issue using "certain combinations of browser plugins and
HTTP redirects". The new patch for Ruby on Rails forces both of these
components to be in the request, preventing exploitation.
A hidden flash file on a website will automate the sending of the following
request:
http://www.attacker.com/redirect.php?status=307&url=http://www.victim.com
Flash will allow the site which it is running from to specify POST data and
additional headers. But before sending the request, it will check the sites
crossdomain.xml file. The attacker will set up their cross domain.xml file
as follows.
http://www.attacker.com/crossdomain.xml
[http://www.attacker.com/redirect.php?status=307&url=http://www.victim.com]
POST / HTTP/1.1
Host: www.victim.com
…
X-Header: test=data;
Cookie: abc=123
Content-Length: 9
We see here that the POST request is being set to www.victim.com, with the
additional headers and the POST body. Web server frameworks can no longer
rely on the implied security of additional HTTP Request Headers alone to
prevent CSRF.
Breakdown of the vulnerability:
Mac - Flash Player 10,2,154,12
Chrome 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
Testing the vulnerability yourself:
The Web Security Mailing List
WebSecurity RSS Feed
http://www.webappsec.org/rss/websecurity.rss
Join WASC on LinkedIn http://www.linkedin.com/e/gis/83336/4B20E4374DBA
WASC on Twitter
http://twitter.com/wascupdates
websecurity@lists.webappsec.org
http://lists.webappsec.org/mailman/listinfo/websecurity_lists.webappsec.org