— it can be assembled out of parsing quirks,\nand a single line can stack eleven of them at once:\n-->'\"/>
\" ontoggle=(co\\u006efirm)``>\n\nRead left to right, every fragment defeats a different assumption:\n\n\n\nFragment\nWhat it defeats\n\n\n\n\n-->\nescapes an HTML comment context — a filter that assumed the input stays commented out\n\n\n' then \"\nbreaks out of a single-quoted attribute, then a double-quoted one, covering both without knowing which is in use\n\n\n/>\ncloses whatever tag is still open\n\n\n\nescapes a JavaScript context, in mixed case so a blocklist matching the literal misses it\n\n\n
\na less well-known tag (
) that a blocklist of script / img / iframe never enumerated\n\n\nopen\nmakes the element render already expanded, so the handler fires with no user interaction\n\n\nx=\">\"\na dummy attribute whose value mimics a tag close, to derail a naive parser\n\n\nontoggle=\na less well-known event handler — again, not on anyone's list\n\n\nco\\u006efirm\nthe function name confirm written with a Unicode escape, so searching for the literal text fails\n\n\n(…) around the name\nparentheses wrapped around the function name, so the literal string confirm( a denylist searches for never appears\n\n\n``\nbackticks invoke the function instead of () — a tagged template call, so a filter looking for a call's parentheses sees none\n\n\n\nThe lesson is a counting argument, not a matter of taste. There are well over a hundred tags,\ndozens of event handlers, several nested parsing contexts and multiple encodings for the same character — a\ndenylist has to be right every single time, an attacker only once. Framework escaping wins because it\nworks the other way round: it encodes whatever the data is for the context it lands in, so a novel\ntag or a brand-new handler needs no new rule. Use it, and never switch it off for untrusted data.\nGo deeper:\n\n OWASP XSS Filter Evasion Cheat Sheet — the catalogue of bypasses a hand-rolled filter has to beat.\n\n", "dateModified": "2026-07-31T12:08:47+00:00" } } }

HELP

Quiz Entry - updated: 2026.07.31

Why should you rely on framework protections against XSS?

Because XSS payloads exploit dozens of obscure parsing quirks (case tricks, Unicode escapes, comment breakouts) that hand-rolled filters miss — framework escaping is battle-tested against all of them.

A hand-rolled filter can only block the tricks its author thought of. The trouble is that a payload need not look anything like <script>alert(1)</script> — it can be assembled out of parsing quirks, and a single line can stack eleven of them at once:

-->'"/></sCript><deTailS open x=">" ontoggle=(co\u006efirm)``>

Read left to right, every fragment defeats a different assumption:

Fragment What it defeats
--> escapes an HTML comment context — a filter that assumed the input stays commented out
' then " breaks out of a single-quoted attribute, then a double-quoted one, covering both without knowing which is in use
/> closes whatever tag is still open
</sCript> escapes a JavaScript context, in mixed case so a blocklist matching the literal </script> misses it
<deTailS …> a less well-known tag (<details>) that a blocklist of script / img / iframe never enumerated
open makes the element render already expanded, so the handler fires with no user interaction
x=">" a dummy attribute whose value mimics a tag close, to derail a naive parser
ontoggle= a less well-known event handler — again, not on anyone's list
co\u006efirm the function name confirm written with a Unicode escape, so searching for the literal text fails
(…) around the name parentheses wrapped around the function name, so the literal string confirm( a denylist searches for never appears
`` backticks invoke the function instead of () — a tagged template call, so a filter looking for a call's parentheses sees none

The lesson is a counting argument, not a matter of taste. There are well over a hundred tags, dozens of event handlers, several nested parsing contexts and multiple encodings for the same character — a denylist has to be right every single time, an attacker only once. Framework escaping wins because it works the other way round: it encodes whatever the data is for the context it lands in, so a novel tag or a brand-new handler needs no new rule. Use it, and never switch it off for untrusted data.

Go deeper:

From Quiz: SPRG / Input Validation & Output Encoding | Updated: Jul 31, 2026


© 2026 Mission Control - Cyber Space Training | About | Feedback