Authorization disclaimer. This walkthrough is limited to the intentionally vulnerable PortSwigger Web Security Academy lab linked below. Test only systems you own or are explicitly authorized to assess.

Overview

This lab isolates HTML parser closes an escaped JavaScript string. Both single quotes and backslashes are escaped inside var searchTerms, but the value remains inside an HTML script raw-text element. The HTML parser recognizes the closing script token before the JavaScript parser interprets the quoted value, then parses the attacker-supplied script element.

Lab objective/setup

Open the Academy exercise at the reserved lab URL and work only in that disposable environment. The required proof is specific: The second script executes alert(1) and the Academy marks success.

What I observed

Both single quotes and backslashes are escaped inside var searchTerms, but the value remains inside an HTML script raw-text element. The HTML parser recognizes the closing script token before the JavaScript parser interprets the quoted value, then parses the attacker-supplied script element.

Academy objective states that both single quotes and backslashes are escaped inside a JavaScript string.
Academy objective states that both single quotes and backslashes are escaped inside a JavaScript string.

Why it is vulnerable

The application applies protection for the wrong parser or omits a control at the decisive boundary. In this case, both single quotes and backslashes are escaped inside var searchTerms, but the value remains inside an HTML script raw-text element. Browser parsing therefore preserves the attacker-controlled behavior instead of reducing the value to inert text or a safe URL.

Walkthrough in the authorized PortSwigger lab

First reproduce the recorded page or request and inspect the exact reflected, stored, or DOM-generated context described above. Then supply the following lab payload as data, not as active markup in this article:

1
`</script><script>alert(1)</script>`

The HTML parser recognizes the closing script token before the JavaScript parser interprets the quoted value, then parses the attacker-supplied script element.

Page source shows the reflected value still resides inside an HTML script element, so an encoded closing-script sequence targets the HTML parser rather than the string escape.
Page source shows the reflected value still resides inside an HTML script element, so an encoded closing-script sequence targets the HTML parser rather than the string escape.
Browser alert dialog showing `1` after the HTML parser ends the original script and parses the injected script element.
Browser alert dialog showing `1` after the HTML parser ends the original script and parses the injected script element.

Verification

The second script executes alert(1) and the Academy marks success. This distinguishes execution from a payload merely appearing in source or being stored without reaching the required event or sink.

Impact and defensive lesson

In a real application, equivalent XSS could act with the victim’s same-origin privileges, expose readable data, or perform authenticated actions. Fix the data flow at its context: use text-only DOM APIs, JavaScript- or attribute-aware encoding, strict URL-scheme allowlists, and maintained sanitization where HTML is unavoidable. HttpOnly cookies and a restrictive CSP reduce consequences but do not repair the injection flaw.

References