Some of you might be familiar with this attack called Self Contained XSS. I recently stumbled upon this article about it. So how bad this kind of attack can be, even though this doesn't have access to the current DOM elements? Has anyone seen this in the wild?

Does this affect mobile browsers too?

Another useful link.

3 Answers 3


Self-contained XSS, is as bad as XSS itself. It's just one of the ways of supplying the payload. The links in your question describe two different vectors:

  1. data: URLs - all modern browsers (including mobile) currently support data URLs in various context and, of course, this gives another vector of supplying XSS payload - and a chance of bypassing many old anti-XSS filters. The most common way is e.g. adding an <iframe> with src of data:text/html,<html><script>alert(/xss/)</script></html>, but there are many, many other ways how to use data URLs for XSS. You can look at some of them by looking for data: at HTML5 security cheatsheet

Has it been used in the wild? Yes, for example I used it to exploit a Piwik XSS vulnerability

  1. The other link described planting an XSS 'shell-like' payload. So, instead of supplying a final exploit, attacker inserts a payload that will request & execute further commands from attacker. Given example is: with(location)with(hash)eval(substring(1)) but there are many similar vectors.

So, to summarize - self contained XSS is not yet another XSS type (like stored XSS or DOM-based XSS), they are just ways of how the payload looks like. You can't really say that it's more dangerous than XSS itself.

  • In recent versions of firefox, data: ᴜʀɪ operate on null. Opera switched to blink for several years know and operate on about:blank like Chrome do. It is now perfectly safe to allow data: ᴜʀɪ on <a> elements (but not javascript: of course). Sep 17, 2015 at 22:28
  • This is not correct (anymore). data: URIs don't always inherit the origin, so in those cases the impact would not be "as bad as XSS itself".
    – Arminius
    Jul 21, 2017 at 11:55

This is actually an old issue. You can encode any media type using the data URI. It's quite common to use it for embedding images in a single markup file.

<img src="data:image/png;base64,ABCdefghIjKlmNoPqrSTuvwxyZ01d" />

The reason this is dangerous is that any XSS attack could allow an attacker to embed a data URI. If the user downloads it, they could be accessing any kind of file. What's worse, it's a way to embed data that can exploit other vulnerabilities in browsers or underlying rendering components, from a site that the user trusts.

For example, imagine Bob's Crazy Discount Spoons had an XSS attack in which an image's src can be manipulated:


The user now gets a nasty payload exploiting a vulnerability in his browser's PNG renderer, instead of those crazy discount spoons he desired.

Of course this isn't limited to images. Any place where you can inject into an object's source or link, it can be used. The same applies for being able to inject this kind of data into full HTML injection attacks.


So how bad this kind of attack can be, even though this doesn't have access to the current DOM elements?

It's worse than the rather limited examples in the linked article: in Firefox and Opera, data: URIs do operate in the same security context as the document that includes them, and so can access DOM elements in your domain. This doesn't happen in Chrome/Safari, or IE9 (which deliberately has only partial support for data: URIs).

In the case where HTML documents can be included, this delivers all the same risks as conventional XSS. That's primarily frames and links, but other attacks are possible(*).

example: http://jsbin.com/ukoqot/2/ - creates a link and an iframe, injecting the HTML document you type into data: URLs in both. Code in the linked/framed document picks up the security context of jsbin.com, allowing it to alert the source code of the jsbin index page.

Consequently you should consider data: URIs to be just as risky as javascript: URIs, and disallow them everywhere your webapp permits URIs to be submitted. (Really, whitelisting known-good URI schemes to stick to a limited selection such as http/https is best.)

(*: For example: put an attacker-submitted data:text/html... URI in an <img src> and the image won't work. But if the user can be duped into right-click-view-image, they'd load the resource as HTML, resulting in XSS.)


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .