Bugs In The Browser Firefox's DATA URL Scheme Vulnerability

Thu, 01 Nov 2007 01:39:19 GMT
by pdp

I will be as brief as possible. Here is the deal: attackers are able to launch Cross-site scripting attacks from any origin (kind of like universal XSS) or escalate their privileges to chrome (not trivial) by tricking the victim into performing an action, such as clicking on a link. The issue was found and tested on the latest Firefox release.

The vulnerability was discovered within the way Firefox handles the data: URL scheme. The data URL protocol is used to compose inline data streams, such as images, audio and video files, HTML pages, etc, etc, etc. According to the almighty Wikipedia:

The data: URI scheme defined in IETF standard RFC 2397, is an URI scheme that allows inclusion of small data items inline, as if they were being referenced to as an external resource. They tend to be far simpler than alternative inclusion methods, such as MIME with cid: or mid:. According to the wording in the RFC, data: URIs are in fact URLs, although they do not actually locate anything.

To cut the long story short, a problem occurs due to the fact that Firefox threats data: URLs the same way as javascript: URLs, i.e the origin of the generated content does not point to about:blank but to the initiating parent. Therefore, websites which allow user-supplied content but does not sanitize data: URLs when supplied as part of links and other dynamic components, could result into compromising the security of the visiting users and potentially the security of the hosting site.

It is also possible to escalate to chrome privileges, although it is not that trivial. This type of vulnerability can be used successfully on various types of extensions such as RSS feed readers, and in general browser components that make use of URLs extensively, to escape from the restricted sandbox and jump into the chrome from where attackers will be able to completely hijack the victim's browser, install badware to snoop on to private data that comes in and goes out and perform other malicious and illegal activities.

The simplest way to test and verify the bug is to create and host a page on a server, which contains the following text:

<a href="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTs8L3NjcmlwdD4=">test</a>

When you click on the "test" link, pay attention on the alert pop-up title (the text inside the blue gradient if you are on Windows). Obviously the origin is still within the same context as the parent. This shouldn't be the case. If the same link is posted to myspace.com, attackers will successfully execute a Cross-site scripting attack, which is wormable, although it will not be as severe as the Samy worm. As I mentioned before, similar tactics can be used against known Firefox extensions and the Firefox browser itself in order to gain chrome privileges.

When I discovered this issue I thought that this is the intended behavior enforced by the browser. After investigating Opera and Safari for similar problems and reading more about data: URLs, it was more then clear that an inherent vulnerability is present within the Firefox browser. The best way to protect yourself from this kind of attack is to use white rather then black listings, i.e. you allow only http: and https: protocols, instead of allowing all protocols apart from javascript:. These tactics are applicable to both Web and Extension developers.

Archived Comments

I used to use the data directive quite a fair bit to bypass filters and in fact my first myspace exploit used it. http://www.criticalsecurity.net/index.php?showtopic=14573&hl= You can also use base64 in the meta tag
<META http-equiv="refresh" content="5;URL=data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTs8L3NjcmlwdD4=">
or drop the base64 altogether
you can also use it to get the use to be prompted to download files but i haven't worked out how to make that work correctly yet
Out of curiosity, what exactly in that data: spec led you to think that this is not the right behavior? As you say, schemes should be whitelisted, not blacklisted when filtering; otherwise any non-HTTP scheme exposed by the UA is a possible exploit vector against the site... Giving data: the origin of its loader has the obvious benefit that one can communicate back and forth with an loaded via a data: URI. As for extensions, they are supposed to do security checks on all URI loads. And in most cases they want to use the "disallow loads that inherit the origin" flag to said security check. Any extension that doesn't do that is in for a world of hurt, and not just due to data:. It's easy to abuse other protocols (file:// comes to mind) if the extension blindly loads them.
Oh, and as a side note changing this behavior will in fact break sites that use data:. Given that the sites that are "vulnerable" are simply using buggy filtering (and need to get fixed no matter what happens with data:), it's a tough tradeoff.
Jesse RudermanJesse Ruderman
This is the behavior intended by Firefox developers. Firefox developers are aware that it can lead to XSS in poorly coded sites and that Safari and Opera behave differently. See discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=255107. Netscape 4 has "mocha:" and "livescript:", and IE has "vbscript:", so it has never been the case that blacklisting just "javascript:" in web applications was safe. This wasn't exactly secret. The bug report is not hidden, and http://ha.ckers.org/xss.html and http://www.squarefree.com/securitytips/web-developers.html both mention data: URLs as potential XSS vectors.
very nice, again. i found one foul in your's text
The best way to pro[j]ect yourself from this kind of attack
digi7al64, nice! Boris and Jesse, first of all, the reason I've put this together is mainly to inform about my personal surprise that actually this thing works. I've been playing with data urls for ages, though never new they are executed within the context of the calling page. Of course it makes sense but, because, as you said, the caller needs to communicate somehow with the spawned page, you have to allow this type of communication. Though, not Safari nor Opera follow Mozilla's design decision. So, even if this is the intended behavior, you guys have a lot of work to do in order to make sure that developers clearly perceive data: URLs as javascript: URLs. Yes, this vector has been in the xss cheat sheet for ages. I wrote about it like an year ago over here. RSnake, the guy who put the cheat sheet, has responded on this with the following:
This has been on the XSS Cheat Sheet for nearly two years and has been documented elsewhere for years before that. It’s no different than the javascript: directive in a URL. This isn’t new. It’s useful for certain things, like building CSRF tools, but cookie theft is not one of them.
One thing is for certain, there are tones of vulnerable sites and extensions due to this data: URL scheme behavior, mainly because of the lack of education. And no, it is not the same as file: or any other URL protocol. These protocols are successfully blocked by the browser when served from http: and https: origins.
To chime back in I believe data: is an unnecessary, unsafe and useless protocol that should never have been developed and it provides no real benefit other then to introduce a new security risk. I mean it serves no real purpose, I can use ajax for client to server communications, javascript to control the gui, xml for data and xslt for style. The only _real_ benefit is image generation and even then why would generate images on the fly. There are already many and fair better ways to deliver image and rich media content to the screen. Mozilla should just drop it and let it die.
Wladimir PalantWladimir Palant
Heh, now you got us all very intrigued - and then this. Just another XSS vector that has been known for ages. Not exactly a vulnerability in the Firefox browser but very much the expected behavior (if I embed a frame with data: in my web page I expect it to have access to the main page).
One thing is for certain, there are tones of vulnerable sites and extensions due to this data: URL scheme behavior
Sure. And every site that filters links using a blacklist will be vulnerable to *something*. But most sanitizing attempts don't go much beyond filtering out the word "javascript" (and we don't need the XSS cheat sheet to know that this is not nearly enough). This is an education issue of course, but one that we probably won't see solved in the next few years. Note that Firefox no longer allows HTTP redirects to data: URLs. Blind redirects are very common and this was making each of them an XSS vulnerability.
Wladimir, it does not only work by embeding an iframe as you suggested, but it also works by clicking on a link which contains the data: directive. It still works even when the link target is set to _blank. Pages opened in new tabs by do not inherit the caller context, do they? The data: url scheme makes pretty much every application vulnerable to XSS by default when browsed with Firefox. Moreover, there are poor understandings among Extension writers what data: can do. If it is not a vulnerability then it is one of the biggest disinformation experiment ever. Why Safari and Opera does not follow Firefox's behavior?
another reason why context propagation in data: URLs is a bad news is provided by Stefano Dipaola over here.
nice one pdp
Heh. I used data: a few months ago to get a backframe payload in ;) AFAIK all recent versions of noscript detect malicious DOM in data: Good times... Good times...
also version affected this vulenerability
Not sure what kofi is talking about. This behavior hasn't changed since sometime in 1999 or 2000.
for firefox 1.5 this behaviour is simply not there.
i blogged about this a few months ago http://qqq3468349856.blogspot.com/2007/08/why.html
this is awesome, I am very much interested in the other variants of data:. can you get some POCs to show how they work?