PortSwigger XSS Lab: Stored XSS
Stored XSS into anchor href attribute with double quotes HTML-encoded

Description
This lab contains a stored cross-site scripting vulnerability in the comment functionality.
Task
To solve this lab, submit a comment that calls the alert function when the comment author name is clicked.
Methodology
Add the Target URL in Burpsuite Scope
This is our target website

As per the description, the XSS vulnerability is present in the comment section
Click on any post. Scroll down to the comment section. Open the dev console.
Lets add a new comment in the comment section of the blog as shown in the below image

After that, go back to the blog to view the newly added comment

Lets check the comment author name where the XSS vulnerability might be present
Analyze the comment author name and view its code in the inspector tab

As seen in the above image, the
hrefattribute stores the Website form parameter. It stores them as a hyperlink (which is clear from the<a>tag)If we click on the comment author name, we would be redirected to the hyperlink inside the
hrefattributeSo, if we want to trigger XSS, we have to store the payload inside the
hrefattributeHere, we can use the concept of Hierarchical and Non-Hierarchical URLs
Hierarchical URL:
They follow the structure
scheme://authority/path?query#fragmentExample:
https://example.com/path/to/page
Non-Hierarchical URL:
No
//authoritypart — structure depends entirely on the scheme definition.Example:
javascript://
Note: A short summary will be given for the concept of Hierarchical and Non-Hierarchical URLs above. For further explanation, kindly visit the bottom of the current page
We can use the
javascript://- non-hierarchical URL to run inline JavaScript code. It’s used to execute JavaScript directly when a link or address bar is used.Example:
javascript:alert('Hello World');When this URL is visited (for example, in a browser address bar or
<a href>), the browser executes the JavaScript code instead of loading a page.
Using the above information, we will now create the below XSS payload
javascript:alert(1);Lets add this payload inside the Website link form parameter by creating a new comment. Click on the Post Comment button

As soon as we submit the comment, we can see a notification that we have successfully solved the lab

Lets try to invoke the XSS payload stored inside the
hrefattribute of the comment author name inside the<a>tagWe will go back to the blog and analyze the author name hyperlink

As seen in the above image, the Stored XSS Payload has successfully saved inside the
hrefattributeTo invoke the payload, click on the comment author name
Wolf3
We have successfully triggered Stored XSS on the target website
Using the above payload, we have used the non-hierarchical URL
javascript://to run inline javascript code inside thehrefattribute of the<a>tag belonging to the comment author name. Thereby, executing a Stored XSS on the target website
Hierarchical v/s Non-Hierarchical URL
URL classification in RFC 3986
According to RFC 3986 (Uniform Resource Identifier: Generic Syntax),
URLs (URIs) can be broadly categorized as:
| Type | Example | Hierarchical? | Explanation |
| Hierarchical | https://example.com/path/to/page | ✅ Yes | They follow the structure scheme://authority/path?query#fragment. |
| Non-hierarchical | mailto:logan@example.com | ❌ No | No //authority part - structure depends entirely on the scheme definition. |
Structure of a hierarchical URL
Hierarchical URLs have this general pattern:
<scheme>://<authority><path>?<query>#<fragment>
Example:
<https://example.com/blog/article?id=10#comments>
Here:
scheme=httpsauthority=example.compath=/blog/articlequery=id=10fragment=comments
Because of this structured layout, these URLs can be resolved relative to one another, e.g.,
/blog/article relative to https://example.com → hierarchical traversal is possible.
Structure of a non-hierarchical URL
Non-hierarchical URLs omit the authority and path entirely.
They don’t follow the // or / folder structure.
Instead, the content after the scheme is directly defined by that specific protocol’s syntax.
Examples:
| Scheme | Example | What it means |
mailto: | mailto:logan@example.com | Open default email client to send mail to that address |
tel: | tel:+919999999999 | Open phone dialer with number |
data: | data:text/plain;base64,SGVsbG8= | Embed inline data (e.g., text, image) |
javascript: | javascript:alert('XSS') | Execute inline JavaScript in browser context |
All of these are defined independently of hierarchical syntax — they don’t have //authority or path.
How browsers parse non-hierarchical URLs
When a browser sees a URL:
scheme:something
it checks whether the scheme’s definition uses hierarchical syntax or non-hierarchical syntax.
If the scheme is non-hierarchical, the browser:
Skips the authority and path parsing steps.
Passes the rest of the text (after the colon) directly to that protocol’s handler.
Executes the handler defined in the browser or OS.
Example breakdown
mailto:logan@example.com
Scheme:
mailtoRemainder:
logan@example.comBrowser action: Open mail client with “To” filled in.
javascript:alert(1)
Scheme:
javascriptRemainder:
alert(1)Browser action: Execute code in page context.
Security considerations
Because non-hierarchical schemes bypass normal navigation and go straight to browser handlers:
javascript:can lead to XSS or bookmarklet abuse.data:can embed inline malicious payloads.mailto:andtel:can be used in phishing/social engineering.
Hence, modern browsers restrict them:
Many contexts block
javascript:URLs (insideiframe,a hrefin sandboxed pages, etc.).CSP (Content Security Policy) can disable
javascript:entirely viascript-src.


![Lecture 4 - Rediscovering Process Scheduling [Part - 1]](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1765604682888%2F80e6cf20-aded-4aac-8c75-affdd35615b2.jpeg&w=3840&q=75)

![Lecture 3 - Reinventing MMU [Part - 2]](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1763234243271%2F6bb1c737-9def-4975-a06d-7ca59791c881.png&w=3840&q=75)
![Lecture 2 - Reinventing MMU [Part - 1]](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1762492010507%2F7db0bf79-265d-41bc-990f-0cb2c68e61f2.jpeg&w=3840&q=75)