An XSS polyglot is a payload that can execute JavaScript in more than one injection context.
I wrote this one for the XSS Polyglot Challenge. The goal was to make a short payload work across multiple contexts:
javascript:`/*\"/*--><svg onload='/*</template></noembed></noscript></style></title></textarea></script><html onmouseover="/**/ alert()//'">`
My AwesomeXSS collection has a version with %0a at the start.
Injection contexts
The injection context is where your input ends up in the page. Here are a few examples:
- HTML attribute:
<div name="[payload]"> - JavaScript string:
<script>var x = "[payload]";</script> - HTML comment:
<!-- [payload] --> - Textarea content:
<textarea>[payload]</textarea> - URL:
<a href="[payload]">
I cover choosing a payload for the context and working around filters in my paper, Bypassing XSS Detection Mechanisms.
I’ve also collected context-breaking examples in AwesomeXSS.
URL scheme, quotes and comments
javascript:`/*\"/*-->
javascript:makes this a JavaScript URL. The browser runs the code after it when you navigate to the URL./*marks the start of a JavaScript block comment.-->closes an HTML comment.
A double quote can close a double-quoted HTML attribute. In a JavaScript string, though, \" is an escaped quote, so it doesn’t close the string.
HTML end tags
<svg onload='/*</template></noembed></noscript></style></title></textarea></script>
If the payload lands in a textarea, </textarea> closes it so the browser can parse the rest as HTML. There are closing tags for template, noembed, noscript, style, title and script too.
In HTML text, < becomes a literal <. It stays text, so <svg doesn’t become an SVG element on that parse.
Event handler
<html onmouseover="/**/ alert()//'">
When the HTML parser is in its in body mode, this <html> tag adds any missing attributes to the existing root element. It ignores the tag if there’s a template element on the stack of open elements.
The handler runs on mouseover. /**/ is an empty comment, alert() opens the alert box and // comments out the trailing apostrophe.