Evasion ladder

levels 1–2

Active filter:

Switch level: Level 1 Level 2
Method — read the filter, don't fight it
  1. Baseline on every level: <u>test one, two, three</u> — proves HTML lands raw (no encoder) and there's no CSP (inline executors like ours run fine).
  2. <script>alert(1)</script> fails. Before escalating, ask: which part of my input changed? The source view will tell you letter for letter.
  3. Change ONE variable at a time. Swap the function next: <script>confirm(1)</script> — if that dies too, the filter is watching the tag, not the JS call. This is trial and error with discipline, not guessing.
  4. Level 1 assumption: filters are often hardcoded strings. If the filter saw lowercase script and ate the tag, maybe it never checks other cases. Case-mix is the cheapest test — always try it first.
  5. Level 2 assumption: a regex that eats the full tag. Watch what lands in the source view — does the SECOND half of a doubled payload survive?
  6. Whichever assumption holds, leverage the surviving piece — the whole discipline is trusting small things that work.
Spoiler — Level 1: case-mix
<sCript>alert(1)</sCript>

The filter only knows the lowercase literal <script — mix case anywhere in the tag and it sails through. Spectrum applies to any tag: <iMg, <oNeRRoR… Cheapest bypass you'll ever meet; always test it before anything clever.

Spoiler — Level 2: duplicate payload
<script>alert(1)</script><script>alert(1)</script>

The regex eats ONE full element per pass — the first. The duplicate comes out intact in the source view and executes. Same reflex works at word level too: <sCrcript>-style nesting occasionally survives single-pass word strips on other targets.