Defined Misbehaviour

Web security, programming, reverse-engineering, and everything related.

Yahoo’s Pet Show of Horrors: Leaking a User’s Emails Crossdomain

I’m taking a break from browser security posts while I wait for vendors to patch, so the next few posts are probably going to be about web app security. Hopefully I should have some posts about architectural flaws in browsers / plugins by next month.

Initial Discovery

Since Yahoo recently revamped their Responsible Disclosure program, I figured I’d have a go at finding some vulnerabilities. All of *.yahoo.com is in scope, and Yahoo has a lot of legacy behind it, so I started going through the more obscure subdomains manually. One of the subdomains I looked at a lot was hk.promotions.yahoo.com. It’s a good place to look because it has lots of PHP scripts and Flash, it looks like it wasn’t done by Yahoo’s core devs, and most auditors aren’t looking there since its content is mostly in Chinese.

I ended up on http://hk.promotions.yahoo.com/petshow2011/, apparently a page for a Hongkongese pet show that happened in 2011:

As you can see from the request log, something on the page was requesting data from another domain through a crossdomain proxy: http://hk.promotions.yahoo.com/petshow2011/php/getImages.php?file=<url>.

Crossdomain proxies are generally goldmines for vulnerabilities, and this one’s no different. First of all, it doesn’t whitelist the URLs that we may make requests to, and the proxy is positioned inside Yahoo’s internal network, so we can have it proxy out resources that would normally be inacessible. I tested with a .corp.yahoo.com URL I found on google, and ended up with some uninteresting, but normally inaccessible search statistics. Other SSRF attacks were likely posible, but I didn’t poke it too much other than to verify that local file disclosure wasn’t possible.

Second, since the proxy doesn’t set a Content-Type on the response and we control the response body, we’ve got XSS on hk.promotions.yahoo.com thanks to type sniffing!

Escalating Access

That’s nice and all, but XSS on a mostly-static subdomain isn’t that interesting to me. Now, remember that we control the entire body of the proxy’s response and that there’s no Content-Type. That means we can also proxy an SWF and have it be same-origin with hk.promotions.yahoo.com. Why’s a SWF any more useful to us than HTML? Because of overly-permissive crossdomain.xml rules.

Flash checks for a <destination domain>/crossdomain.xml file before attempting a crossorigin request, to see if SWFs from the sender’s origin may read the response (among other things, see “Further Reading”.) For example, if you wanted to allow SWFs on any subdomain of yahoo.com to do crossdomain reads to your domain, you might put a rule like this in your crossdomain.xml:

1
<allow-access-from domain="*.yahoo.com"/>

That’s probably overly permissive, *.yahoo.com is a lot of attack surface, but let’s take a look at what Yahoo actually has in their crossdomain.xmls.

finance.yahoo.com:

1
2
3
4
5
<cross-domain-policy>
    <allow-access-from domain="*.yahoo.com"/>
    <allow-access-from domain="us.js2.yimg.com"/>
    <allow-access-from domain="*.yimg.com"/>
</cross-domain-policy>

www.flickr.com:

1
2
3
4
5
6
7
<cross-domain-policy>
    <allow-access-from domain="*.yahoo.com"/>
    <allow-access-from domain="l.yimg.com"/>
    <allow-access-from domain="d.yimg.com"/>
    <allow-access-from domain="s.yimg.com"/>
    <site-control permitted-cross-domain-policies="master-only"/>
</cross-domain-policy>

ca-mg5.mail.yahoo.com (webmail server, returns valid crossdomain.xml when logged in):

1
2
3
4
5
<cross-domain-policy>
    <allow-access-from domain="*.yahoo.com" secure="false"/>
    <allow-access-from domain="l.yimg.com" secure="false"/>
    <allow-access-from domain="s.yimg.com" secure="false"/>
</cross-domain-policy>

YMail actually has the least secure crossdomain policy of any of the subdomains that I checked. That secure="false" will allow SWFs served over HTTP to read resources only served over HTTPS, making the forced HTTPS a lot less useful. Per Adobe, “Using false in an HTTPS policy file is not recommended because this compromises the security offered by HTTPS.”

It’s Proxies All the Way Down

Well, now we know we can get an arbitrary SWF same-origin with a subdomain of yahoo.com, and we know that SWF can read from a number of subdomains on yahoo.com, let’s get some emails!

First, we need to pick the SWF to proxy. The obvious choice for someone who doesn’t know Flash well is a SWF<->JS XHR proxy. These allow you to proxy requests from JS through a specialized SWF. Here was the result, with some overzealous redaction:

Looks like our proxied proxy works, the response body includes all of my test account’s auth tokens and personal info. One of those tokens allows us to access a JSON endpoint that lists our e-mails:

and we can use those message IDs to pull up specific emails from the user’s inbox:

and since we can read pages containing CSRF tokens, we can delete the user’s emails, send emails as the current user, etc:

Funky. The most obvious application of this attack would be to determine the user’s email, initiate a password reset on any “interesting” sites, read the password reset URL from their email, then delete the email; but there’s plenty of others.

The Fix

Well, the affected page was for a Hongkongese pet show that happened in 2011, so the fix was removing the page and its associated crossdomain proxy. I’m disappointed that the crossdomain.xml rules are still as loose as they are, but I don’t think that’s getting changed anytime soon. Subsequent reports mentioning the crossdomain.xml rules have been marked WONTFIX.

TL;DR

There were SSRF and crossdomain data leakage issues due to a misconfigured crossdomain proxy and overly-permissive crossdomain.xml rules. One was able to leak the emails of the current user, and do anything the user could do from YMail just by having them visit an attacker-controlled page.

This instance of the issue is fixed, but the crossdomain.xml rules are still overly-permissive.

Disclosure Timeline

  • Nov. 19 2013: Discovered that crossdomain proxy leaked internal resources
  • Nov. 20 2013: Reported issue to Yahoo
  • Nov. 23 2013: Updated Yahoo on the XSS / crossdomain leakage / crossdomain.xml issues
  • Nov. 25 2013: Yahoo acknowledges report
  • Nov. 29 2013: Yahoo fixes issue
  • Feb. 03 2014: Yahoo confirms report, bounty elligibility

Further Reading