> For the complete documentation index, see [llms.txt](https://wiki.zacheller.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wiki.zacheller.dev/web-app-pentest/xss/data-urls.md).

# Data URLs

## XSS Attack

[Data URIs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs) allow HTML tags to be created with inline content, rather than reaching out to and making an additional request to the server. For example, an inline image might look like:

```
<img src="data:image/png;base64,iVBORw0KGgoAAAA..."/>
```

So, if we want to run JS we can actually inject either of these into a URL:

```
data:text/html,<script>alert('hi');</script>
data:text/javascript,alert(1)
```

## Definition

Data URLs are composed of four parts: a prefix (`data:`), a [MIME type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types) indicating the type of data, an optional `base64` token if non-textual, and the data itself:

```
data:[<mediatype>][;base64],<data>
```

The `mediatype` is a [MIME type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types) string, such as `'image/jpeg'` for a JPEG image file. If omitted, defaults to `text/plain;charset=US-ASCII`

If the data is textual, you can simply embed the text (using the appropriate entities or escapes based on the enclosing document's type). Otherwise, you can specify `base64` to embed base64-encoded binary data. You can find more info on MIME types [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types) and [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Complete_list_of_MIME_types).

A few examples:

* `data:,Hello%2C%20World!`
  * Simple text/plain data. Note the use of [percent-encoding](https://developer.mozilla.org/en-US/docs/Glossary/percent-encoding) (URL-encoding) for the quote and space characters. Also, for CSV data (MIME type "text/csv"), percent-encoding is needed to preserve the line endings that delimit rows of the spreadsheet.
* `data:text/plain;base64,SGVsbG8sIFdvcmxkIQ==`
  * base64-encoded version of the above
* `data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E`
  * An HTML document with `<h1>Hello, World!</h1>`
* `data:text/html,<script>alert('hi');</script>`
  * An HTML document that executes a JavaScript alert. Note that the closing script tag is required.

{% embed url="<https://www.nccgroup.com/us/about-us/newsroom-and-events/blog/2019/april/a-novel-csp-bypass-using-data-uri/>" %}

{% embed url="<https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs>" %}
