Note: this vulnerability has long been fixed. I was just waiting for the confirmation from Google.
I could now tell a story of magic and wonder, how I spent day and night analyzing GMail and finally after weeks of hard work found this vulnerability. But the truth is that I was simply using GMail as I usually do when I came across this vulnerability.
GMail has had the “View Image” functionality for a while and I’ve often lamented that it doesn’t extend to SVG documents, which are eventually viewed through Firefox anyway. So when I finally noticed the “View Image” link next to an SVG that I had sent to my address for quick access on another computer, I happily clicked on it and was more than a little surprised when it opened on the mail.google.com domain.
You see, hosting any kind of unknown document on your own domain is extremely risky. Even a seemingly harmless PNG or JPEG can be a threat unless you really verify that it is what it claims to be and/or serve it from an unpredictable location. If it’s not and you didn’t notice, then all it takes is a browser trying to act smart and ignoring the MIME type for an attacker to take complete control of the user’s account. SVG is especially dangerous since, just like HTML, it can contain or link in script code. So, seeing the SVG open on mail.google.com was worrying.
On the other hand, GMail also displays HTML on mail.google.com by preprocessing it and removing anything that is not text or formatting-related (which is also an extremely dangerous task since every new release of a web browser includes new ways to load remote data, but apparently Google feels that it’s worth the risk: even allowing the loading of CSS can cause code execution), so there was some hope.
The problem is that in difference to HTML it is nearly impossible to preserve the majority of information in an SVG document if you strip it of tags that can be used to include data, since a lot of SVG’s core functionality relies on linking in fragments that can either be part of the local or any other document.
I started throwing some slightly obfuscated SVGs at it and was surprised to find that it didn’t filter any code at all, no matter how it was included. Using this knowledge and another attack vector (that I’m not going to describe yet since it’s still being worked on) I was able to deliver a harmful mail and open it by leading the user onto a specifically created webpage. With a bit of other black magic I was able to read the address book and all mails from there and have them delivered to my doorstep.
There’s not much more to this story. I reported it, the “View Image” link got disabled for SVG documents and we’re safe once again. But how can such a big issue ever slip through the cracks of Google’s testing and could this happen elsewhere? Well, I can only guess, but this is what it looks like from my perspective:
When you create any kind of software that may be an attack target, you define how potentially dangerous each component is. This may happen informally by people simply watching changes in certain files more closely or through a dedicated process that requires additional reviews for files marked “critical”, but it always happens.
So, how would you rate a file containing a list of image file formats, especially when there are only non-interactive formats like GIF, JPEG or PNG around (as was the case when GMail was initially created)? You’d probably mark it as “safe” and allow patches with minimal or no reviewing. Now, someone learns about this new “image format” SVG, not realizing that it is in fact a document format and adds it to the list of image files and voilà, you’ve got a class A untrusted code execution vulnerability.
What can we learn from this?
- Anything that ends up serving untrusted content from your servers really is security relevant
- Any assumption on the danger of a particular action should be rechecked regularly, to see if it still applies
- A little knowledge is a dangerous thing when it comes to file formats
- When in doubt, serve untrusted content from a separate domain.
Thanks to Adam from the Google Security Team for the good cooperation and being an all-around nice guy 🙂