6 ms·
Flash + 307 redirect = Game Over
- tptacek 16y agoDoh! Sam Quigley called it. In the 307 redirect case, which instructs the client to redirect POST data as well as the bare request, Flash can be coerced into honoring the crossdomain.xml file from the REDIRECTOR site instead of the REDIRECTEE site. * Attackers control redirectors (they can just set up their own). * Flash will set custom headers if crossdomain.xml allows them to. * Rails and Django rely on the fact that attackers can't send custom headers (in particular, the XRW header that told Rails and Django "this is Ajax, don't worry about CSRF"). * So attackers can basically forge the crossdomain policy for arbitrary target sites using Flash, bypassing the CSRF security check in Rails and Django. So much win!
- paulhammond 16y agoThis explains a lot, but thing it doesn't cover is why the patch for Rails ends the session when a CSRF token is missing. I'm guessing this is just extra paranoia, but it opens an obvious attack to log people out of a site maliciously. Any ideas on that one?
- tptacek 16y agoI do not know, and I hope it's just paranoia, because that's a giant pain in the ass.
- smunz 16y agoI guess they forced the end of the session to allow non-session authentication, for example for an Client accessing an RESTful API. I didn't found anything about this, but when you look at the related commit in rails (https://github.com/rails/rails/commit/66ce3843d32e9f2ac3b1da20067af53019bbb034#L1L144 https://github.com/rails/rails/commit/66ce3843d32e9f2ac3b1da...) they also removed the white listing an all non html-requests ("content_mime_type.verify_request?"). So any (api) client modifying XML or JSON resources of an rails app would not be allowed to do so, because of the need to provide the authentication token. Which isn't available for an API client, because there is no session. So instead of throwing an exception to prevent an CSRF-attack they just kill the session to prevent authentication by this session. For an api client this is no big deal, because normally it authenticates with per request credentials. If you don't feel/have the need to support non session authentication, my guess is you could simply overwrite the handle_unverified_request method in your application controller to throw an exception again. But I would wait for further explanation by the rails core team.
- nbpoole 16y agoFortunately, the attack is limited by the fact that the attacker can't see the response from the server. If the attacker could view the response, it would break CSRF protection based on nonces as well.
- bensummers 16y agoWhat if that forged request was to a "create new account" URL, for example? Or to delete something important? Or transfer some money? Do you need to see the response to do bad things?
- dminor 16y agoI think what he's saying is if your CSRF protection is based on a nonce, this vulnerability doesn't break it.
- nbpoole 16y agoNo, but that wasn't my point. My point was that this vulnerability can be (and has been) worked around by using nonces in the header. If you can see the response body, that protection becomes worthless as well (and there is no workaround for that).
- euroclydon 16y agoThis is so difficult to follow. 1) Who hosts the flash app? The site owned by the attacker? Or must the flash app be maliciously uploaded to the site being attacked? 2) And seriously, the final result of this scheme to to make a post to "www.victim.com". Doesn't "victim" mean someone who is exploited? I would expect that data would be taken from a victim, not posted to a victim.
- nbpoole 16y agoIt's actually fairly straightforward 1. It doesn't matter where the SWF is, as long as it can make requests to a redirecting script. That's the point of the attack: you can make cross-domain requests via a redirect. 2. Victim is referring to a victim domain. Pretend victim.com is your bank, and the POST is to send some cash to my account.
- euroclydon 16y agoSo my bank would have to already have a page which returns a 307?
- nbpoole 16y agoNo. Let me try explaining the simplest possible version of this attack. Your bank (http://victim.com http://victim.com) is running its external-facing web application on Ruby on Rails. If you send a POST request to http://victim.com/transfer http://victim.com/transfer, you can transfer money to another person (the recipient is specified in the POST body). The attacker sets up the following things on attacker.com: 1. A page that replies with 307 redirects to a specified destination 2. A Flash applet that makes POST requests 3. A page embedding that applet The attacker sets the applet as if it were making a POST request to http://victim.com/transfer http://victim.com/transfer, setting the X-Requested-With header to bypass CSRF protection. But instead of POSTing directly to victim.com, the attacker POSTs to the redirect script. So the end result looks something like this: 1. Flash checks to make sure that it can make requests to attacker.com (via crossdomain.xml, or by the same origin policy). It can. 2. POST request to attacker.com/redirect is made 3. attacker.com/redirect says "307, the request should go to http://victim.com/transfer http://victim.com/transfer 4. Flash says "OK" and makes the same request but now directed at victim.com 5. After the request has been made, Flash checks the crossdomain.xml file and says "whoops, shouldn't have made that request: you can't see the response."
- wnoise 16y agoHooray flashblock.
- amalcon 16y agoFlashblock would probably not save you. It doesn't actually prevent Flash content from being downloaded and run; it just hides it with CSS. I use NoScript myself, but that tends to break too much by default for most people. When I set up a flash blocker for other people, I give them NoScript in "Allow Scripts Globally" mode.
- nbpoole 16y agoAre you sure about that? Because that's not the way Flashblock describes itself: Flashblock is an extension for the Mozilla, Firefox, and Netscape browsers that takes a pessimistic approach to dealing with Macromedia Flash content on a webpage and blocks ALL Flash content from loading. It then leaves placeholders on the webpage that allow you to click to download and then view the Flash content. It would be pretty useless if all it did was hide the content via CSS.
- amalcon 16y agoWikipedia cites this as the source for that assertion: http://flashblock.mozdev.org/faq.html#fbFlashCookies http://flashblock.mozdev.org/faq.html#fbFlashCookies If it prevented the object from loading, it would block Flash "cookies". edit: Looks like it does call StopPlay() on the movie, which prevents any audio/visual effects.
- nbpoole 16y agoI just tested the extension and I can confirm that Flashblock only downloads and runs the content when the placeholder is explicitly clicked on. So, Wikipedia is wrong. ;) Edit: If I browse to an SWF directly, it does appear to load the content. If I create the SWF via SWFObject, it does not load until I explicitly click on the placeholder. That question is poorly worded. It's referring to blocking Flash cookies in general. Flashblock will not prevent the use of Flash cookies by applets that you allow to run.
- jodrellblank 16y agoAfter a confirmation message that will be unclear to most users i.e. it requests permission?
- sdizdar 16y agoI have a stupid question: Does this vulnerability exist if rails runs https?
- nbpoole 16y agoYes
- EGreg 16y agoWhy don't they use the session nonce instead of double-submit cookies approach to CSRF prevention?