Skip to content

Reflected XSS template literal unicode escaped

Field Value
Platform PortSwigger Web Security Academy
Difficulty Practitioner
Vulnerability Reflected XSS — Template Literal Injection via ${}
Injection Point JavaScript template literal inside <script> block
Goal Execute alert(0) via template literal expression interpolation

Lab — Reflected XSS: Template Literal Injection via ${}

Solution Walkthrough

Searching for teto reveals the injection point is inside a JavaScript template literal:

var message = `0 search results for 'teto'`;
document.getElementById('searchMessage').innerText = message;
Screenshot

All standard escape characters are blocked: <>, ', ", \, and backticks are encoded or escaped. There is no way to break out of the template literal using those characters.

Step 1 — Understand template literal expression interpolation

Template literals (backtick strings) support ${} expression interpolation — JavaScript evaluates whatever is inside the ${} and inserts the result into the string:

var teto = "test";
// Regular string — ${ } is treated as literal characters
console.log("Teto is equals to ${teto}");
// → Teto is equals to ${teto}

// Template literal — ${ } is evaluated as JavaScript
console.log(`Teto is equals to ${teto}`);
// → Teto is equals to test
Screenshot

The ${} syntax only works inside backtick strings — not inside ' or " strings. Since our injection point is already inside a template literal, we can use ${} directly without needing to break out.

Step 2 — Inject an expression

${alert(0)}

Resulting JavaScript:

var message = `0 search results for '${alert(0)}'`;
document.getElementById('searchMessage').innerText = message;
Screenshot

When the template literal is evaluated, JavaScript calls alert(0) to compute the expression inside ${}. Alert fires and the lab is solved :P


Why This is a Unique Context

This lab represents a fourth JavaScript injection context — distinct from all previous ones:

Context Escape character Technique
Single-quoted string '...' ' Close string, inject statement
Double-quoted string "..." " Close string, inject statement
Script block (no string) </script> Close script tag, inject new one
Template literal `...` ${} No escape needed — interpolate directly

Template literal injection is arguably simpler than the others — there is no need to break out of the string at all. The ${} syntax is designed to evaluate JavaScript expressions, and since it already exists inside the template literal context, injecting ${alert(0)} is valid syntax that the JavaScript engine happily executes.