Thanks to the recent recurrence of a vulnerability I wrote about a few years ago and a gentle prod from Simon, I decided it would be good to write about the dangers of cross-domain Ajax with Flash again.
If you read about this story on TechCrunch, note that the "write up explaining all the details" is about an unrelated vulnerability.
I'll try to briefly explain the problem and then show how it relates to Facebook and MySpace. For more background information, please refer to these prior posts:
- Cross-Domain Ajax Insecurity, which discusses why true cross-domain Ajax is a bad idea, despite many misinformed Ajax developers claiming it's safe.
- Cross-Domain Ajax with Flash, the post that discloses the vulnerability.
- The crossdomain.xml Witch Hunt, which mentions other big sites, such as YouTube and Adobe, that suffer from the same vulnerability.
Web technologies that abide by the same-origin policy cannot reside on one site and interact with another. To be a little more specific, if you visit my site, I can't make you update your status on Twitter . If I want to try, I need to get you to send an HTTP request similar to the following:
POST /status/update HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Cookie header in this example, because it's really long.) Would this work? Luckily, no, but only because I have to know the value of your
authenticity_token, Twitter's anti-CSRF token. (Read my article on CSRF for more information about cross-site request forgeries and anti-CSRF tokens.)
To work around this safeguard, I need to get your anti-CSRF token. If you visit Twitter yourself and view source, you can see it:
<input name="authenticity_token" value="snuffleupagus" type="hidden" />
Yes, there is. Meet
XMLHttpRequest(), often abbreviated as XHR, the method most closely associated with Ajax. If I use XHR to send a request from you (to Twitter) and read the response, I can find your token and use that to update your status. Would this work? Luckily, no, because XHR abides by the same-origin policy. I can only use XHR to send requests that are considered to be within the same origin, so I cannot use XHR on my site to send a request (from you) to Twitter, a different site.
crossdomain.xml. Flash supports cross-domain Ajax using an opt-in model, where the receiving site has to give permission. For example, I could make you update your Twitter status if Twitterâ€™s cross-domain policy file let me:
<!DOCTYPE cross-domain-policy SYSTEM
<allow-access-from domain="shiflett.org" />
Luckily for you, Twitter doesn't trust me. More accurately, they don't force you to trust me. This is where open cross-domain policy files like the following are dangerous:
<!DOCTYPE cross-domain-policy SYSTEM
<allow-access-from domain="*" />
A few days ago, Yvo Schaap realized that Facebook Connect not only had an open cross-domain policy file, but also had a complete running copy of the Facebook site. (As evidence, here's the home page within the
www.connect.facebook.com domain. If you're logged in, you'll be recognized.)
If someone can update your status, simpler exploits are also possible. For example, someone can effectively browse Twitter as you, possibly reading private updates from your friends with protected accounts. Because Facebook was vulnerable to this type of exploit, your personal information could have been exposed if one of your friends was exploited, even if you weren't.
MySpace made a similar mistake. Although their cross-domain policy file was not open, it trusted
farm.sproutbuilder.com (Sprout Builder), a site that allows users to upload their own
.swf (Flash) files, thereby gaining complete access to MySpace.
I'm glad Yvo waited until these vulnerabilities were fixed before blogging about them. Unfortunately, I already let the cat out of the bag a few years ago. Hopefully more people will pay attention this time and tread carefully when using
crossdomain.xml. Adobe's own site has finally been fixed, so you no longer have to ignore the hypocrisy of their usage recommendations:
Using a cross-domain policy file could expose your site to various attacks. Please read this document before hosting a cross-domain policy.