June 27, 2026
PortSwigger : Reflected XSS into a JavaScript String with Angle Brackets HTML Encoded
In this lab, the website has a reflected XSS vulnerability in the search query tracking function.
By danar
1 min read
The user input is reflected inside a JavaScript string. Angle brackets like < and > are HTML-encoded, so a normal payload like:
<script>alert(1)</script><script>alert(1)</script>will not work.
The goal is to break out of the JavaScript string and call the alert function.
SOLUTION
First, I accessed the lab and entered a random word into the search box.
Example:
akfgyauiakfgyauiThen I clicked Search.
This step is used to check how the website reflects user input into the page.
After submitting the random word, I used Burp Suite to intercept the request and sent it to Repeater.
In Repeater, I checked the response to see where my input was placed.
From the response, the random string was reflected inside a JavaScript string.
Example:
var searchTerms = 'akfgyaui';var searchTerms = 'akfgyaui';Image placement: Insert the screenshot of Burp Suite showing the intercepted search request here.
Why I Checked the JavaScript String
I checked the response because I needed to know where the input was placed.
In XSS, the payload depends on the context. If the input appears inside HTML, the payload can be different. If it appears inside an attribute, the payload is also different.
In this lab, the input is placed inside a JavaScript string. Because of that, I need to escape from the string first before I can run my own JavaScript code.
Also, angle brackets are encoded, so injecting a new HTML tag is not the right method here.
After knowing that the input is reflected inside a JavaScript string, I replaced the random input with this payload:
'-alert(1)-''-alert(1)-'Then I opened the generated URL in the browser.
Why This Payload Works
The payload used is:
'-alert(1)-''-alert(1)-'The first single quote:
''is used to close the original JavaScript string.
For example, before injection, the JavaScript may look like this:
var searchTerms = 'akfgyaui';var searchTerms = 'akfgyaui';After the payload is inserted, it becomes similar to this:
var searchTerms = ''-alert(1)-'';var searchTerms = ''-alert(1)-'';The alert(1) part is JavaScript code that shows an alert pop-up.
The minus symbols:
--are used to make the payload still valid JavaScript syntax after breaking out of the string.
So, the browser reads the injected value as JavaScript code, runs alert(1), and shows the alert box.
After loading the payload URL, the browser executed the JavaScript and showed an alert pop-up.
After the alert appeared, the lab status changed to Solved.
This lab shows that XSS can happen even when angle brackets are HTML-encoded.
Because the input was reflected inside a JavaScript string, I did not use a normal HTML tag payload. Instead, I used:
'-alert(1)-''-alert(1)-'The payload closes the JavaScript string, runs alert(1), and keeps the JavaScript syntax valid.
From this lab, I learned that input filtering must depend on the context where the input is placed. If user input is inserted into JavaScript, it must be properly escaped so it cannot break out of the string and execute code.
Thanks for your attention.