Write-Up by Aditya Bhatt | DOM-Based XSS | innerHTML Sink | BurpSuite
Lab Link: https://portswigger.net/web-security/cross-site-scripting/dom-based/lab-innerhtml-sink
This PortSwigger lab contains a DOM-based XSS vulnerability inside the blog’s search feature. The JavaScript takes user input from location.search and injects it directly into the page using innerHTML, making it instantly exploitable.
We first load the lab to observe how the search function behaves and how input flows through the DOM.
➤ Why? Understanding the initial page structure helps identify where user-controlled data appears.
We start with something harmless like test to see how the application handles reflection.
➤ Why? A baseline request shows how the input appears in the DOM, which is crucial for confirming a sink like innerHTML.
The HTML reveals that the search term is directly injected via innerHTML, confirming unsafe behavior.
➤ Why? This proves that location.search → innerHTML, which is a classic DOM XSS pattern.
<svg onload=alert(1)>
Paste it in the search bar and click Search.
➤ Why this payload works?
<svg>is a powerful XSS vector processed by the browser even without visible rendering.onloadexecutes as soon as the SVG is parsed.- Since innerHTML interprets input as real HTML, the JS engine executes the event handler instantly.
This confirms the DOM XSS vulnerability.
<img src=1 onerror=alert(1)>
This also works.
➤ Why this payload works?
imgtag attempts to loadsrc=1, which is invalid.- Image loading fails → triggers onerror → fires
alert(1).
This payload relies on the fact that SVG elements fire onload as soon as the browser parses them.
Perfect for innerHTML-based DOM XSS, because the browser immediately executes the event.
✓ No need for external resources
✓ Executes instantly
✓ Works even in strict CSP in many cases
This is PortSwigger’s recommended payload.
- The browser tries to load an image from
1 - That fails → triggers the
onerrorhandler → runsalert(1)
This is one of the most universal and reliable XSS payloads.
| Payload | Trigger Type | Reliability | When To Use |
|---|---|---|---|
<svg onload=alert(1)> |
Auto executes on parse | Very High | DOM XSS / innerHTML |
<img src=1 onerror=alert(1)> |
Executes on load failure | Very High | HTML Injection / stored + reflected XSS |
Both are excellent — the SVG payload is preferred for DOM sinks, while the IMG payload is preferred for server-side injection.
DOM XSS is highly rewarded in bug bounties because:
React, Angular, Vue, jQuery — all vulnerable if unsafe sinks are used.
Since it never touches the backend, WAFs & filters rarely detect it.
Perfect for attacks like token extraction.
Attackers send malicious URLs like:
victim.com/search?q=<img src=1 onerror=alert(document.cookie)>
-
Unsafe JavaScript sinks such as:
- innerHTML
- outerHTML
- document.write
- insertAdjacentHTML
-
Direct use of URL-based sources:
- location.search
- location.hash
- location.pathname
-
No sanitization or encoding The browser interprets injected tags as real HTML.
This prevents HTML parsing entirely.
Removes harmful tags/attributes.
Like < > " '.
Blocks inline script execution.
This lab demonstrates how dangerous innerHTML + location.search combinations are. The moment user input is inserted into HTML without sanitization, attackers can execute arbitrary JavaScript.
DOM XSS is fast, silent, reliable, and common — making it a frequent bug bounty target.
Stay offensive.
— Aditya Bhatt 🔥






