eval.blog

You don’t need xss.rocks/xss.js

You don’t need xss.rocks/xss.js

Many people focusing on XSS seem to miss out on one simple yet powerful thing: data URLs. While finding an XSS, hackers test the vulnerability with some hosted solution like xss.rocks or host their files. But most of the time, you don't need a hosted javascript file. You can simply use data URLs.

What is a data URL

Data URLs are a special kind of URL defined with a data scheme. They work similar to normal URLs and allow you to embed the code in the URL itself. They can be declared with any content type and also can be encoded in base64! Data URL have the following structure:

data:[declarations],[data]

You can have multiple declarations delimited by semicolons.

data:text/html;charset=utf-8;base64,PGgxPkhlbGxvLCBXb3JsZCE8L2gxPg==

Declarations can be juggled except the content type declaration. The following will fallback to the default content type text/plain:

data:charset=utf-8;text/html;base64,PGgxPkhlbGxvLCBXb3JsZCE8L2gxPg==

But this is fine:

data:text/html;base64;charset=utf-8,PGgxPkhlbGxvLCBXb3JsZCE8L2gxPg==

All fields are optional except for the scheme that is, data. The following will give a blank page:

data:;,

Usefulness

There are times when Content Security Policy is tight enough to block any external javascript but allows data URLs. Note that data URLs are treated as an external resource by the browser and will be blocked if Content Security Policy doesn't allows it. So if you can't get XSS via an externally hosted javascript file due to CSP, you might be able to get an XSS via data URLs. But it is not always the case.

As data URLs are more flexible way than the hosted files ie. writing code, saving them and then hosting them is way too much work for me at least. Also, you get base64 encoding on the go. So why not use data URLs where you can?

Text in data URL

The most basic format you can get is just text:

data:;,Hello, World!

HTML in data URL

Writing HTML is just a matter of declaring the content type text/html:

data:text/html;,<h1>Hello, World!</h1>

But HTML in the URL is ugly. So let's make it base64.

data:text/html;base64,PGgxPkhlbGxvLCBXb3JsZCE8L2gxPg==

There is no need for decoding. It is done by browser automagically.

JavaScript in data URL

As a xss.rocks (or any other hosted javascript files) alternative, you can simply use:

data:text/javascript;,alert('xss')

Obviously, this might trigger WAF. So simply base64 it.

Misc

Data URLs are awesome as you can type in your test files on the go without taking the effort to host one. Also, it is not limited to what the browser renders. You can have any content type and make files on the go!

data:hackers/realm;,{"mongodb_succs":"' || 1==1 %2500"}

And yes. Any charset as well:

data:;charset=euc-jp,もし もし

If the browser can render, it will:

data:image/svg+xml;,<svg onload="alert('g33z')"></svg>

You can use them in the script tag:

<script src="data:text/javascript;,alert('lets share your password with the world')"></script>

But, links don't work. You might wanna use a hosted file here.

<a href="data:text/html;base64,PGgxPkRvbnQgY2xpY2sgaXQgYnJ1aCEgSnVzdCBraWRkaW5nLi4uPC9oMT4=">Data URLs in a link don't work.</a>