Solution for PortSwigger Academy Lab: Reflected XSS in canonical link tag
The following is my documentation on PortSwigger’s Academy labs.
End Goal: Perform an XSS attack on the target page that injects an attribute that calls the alert function
This Lab requires us to exploit a vulnerable canonical link tag. If that sentence did not sound like Klingon to you then qapla’! You probably don’t need to read this! If, however, you are like me and need a better understanding of what a canonical link has to do with XSS, stick around!
Investigating the target site
It appears that the fictional webmasters of our target site got a little frustrated with all of the exploits we were performing in their search box and instead of continuing to mitigate those attacks they elected to be done with it and remove the search box entirely. Fair enough, but how can we exploit the site with an XSS attack now that it is gone? Let’s take a look at the background of the site and see what we can find.
First, we inspect the page with our Firefox’s Dev Tools, looking for anything in the backend that we can play with. If we start from the top, we find the following pretty quickly:
Canonical links
In the head tag of the site, we come across our canonical link:
<link rel="canonical" href="https://YOUR-LAB-ID.web-security-academy.net/">
“The rel attribute defines the relationship between a linked resource and the current document.”1
In this case, rel helps “canonical” define…
“…the preferred URL for the current document, which helps search engines reduce duplicate content.”2
On the surface, this is just there to make things as SEO-friendly as possible. For our purposes, however, we are in a little bit of luck: the URL is being reflected in this tag. We can see this by going to another post on this target site:
Our URL in the address bar matches that of the canonical link in the head tag of that post. What happens if we append that address bar with something risky?
Crafting our XSS canonical link exploit payload
Why mess with the classics? Head to the address bar and append the URL with:
/?'onclick='alert(1)
We have successfully reflected our attack into the canonical link, which is good, it means that the target site is not scrubbing our script out, but we have not got any kind of alert, and our lab remains “not solved”. This is an interesting problem we need to figure out. Our payload exists solely in the background, hidden from any kind of user interaction. How do we change that?
This is where accesskey comes into play:
“The accesskey global attribute provides a hint for generating a keyboard shortcut for the current element. The attribute value must consist of a single printable character (which includes accented and other characters that can be generated by the keyboard).”3
In this way, we can have our payload activated without the victim having to see our exploit on the page. We just have to choose a common accesskey to make the likelihood of it being pressed higher. We’ll choose “x”, making our new payload look like this:
/?'accesskey='x'onclick='alert(1)
We only need to place our new payload and append it to our address bar URL.
If done correctly the notification for solving the lab populates!
Inspecting our page we can see the payload was successfully reflected into the link tag.
…but where is our alert?
We’ll pause here to point out that this exploit will only work in Google Chrome. Further, the combination of keys pressed will be different depending on the OS. This is only a concern as you may not be able to see the exploit at work if you are not using Chrome and do not know the specific OS keystrokes. In my case, I was using Firefox in Kali Linux.
Installing Chrome into Kali Linux or: How I Learned to Stop Worrying and Love the Terminal
Woof. At least my lab did not time out this round. First, we need to update…
Then we need to install wget…
…and then we can get Chrome…
sudo install that sucker and open it up, making sure that Firefox does not see you do it. Restart our lab, try out our payload, and press:
Alt+X
…for Linux and…
…we can see our exploit in action!
Potential impact
“If an attacker can control a script that is executed in the victim’s browser, then they can typically fully compromise that user.”4
If this attack were delivered to a victim with a little social engineering (phishing, for example), then just about anything the victim can do on the page is now open to us.
Prevention
Information on WAF (Web Application Firewall), input sanitation, and whitelisting can be found here.
Notes
I am now just a little over halfway done with PortSwigger Academy’s XSS labs. These write-ups have been personally advantageous to me as they really force me to ponder and reflect on what I have learned. Hopefully, they are helpful to others as a happy by-product. In researching for this write-up I found Muhammad Ahmed’s piece on this subject helpful, and my other resources are listed below.
Footnotes
- MDN web docs rel attributes ↩︎
- MDN web docs rel canonical ↩︎
- MDN web docs accesskey ↩︎
- PortSwigger: What is reflected XSS? ↩︎
See anything here that I got wrong? Tell me! Leave a comment below.
Share this:
Filed under: Cybersecurity,Pentesting,PortSwigger Academy,XSS attack - @ January 10, 2024 8:28 am