Difficulty: Practitioner
Vulnerability: Reflected XSS with WAF Evasion & Browser Logic Abuse
Lab Link: https://portswigger.net/web-security/cross-site-scripting/contexts/lab-html-context-with-all-standard-tags-blocked
The objective of this lab was to execute a Cross-Site Scripting (XSS) attack in a search function protected by a strict WAF that blocks all standard HTML tags.
My goal was to inject a custom HTML tag, make it interactive using specific attributes, and force the victim’s browser to execute code automatically upon page load.
I started by testing standard XSS vectos (
Phase 1: Tag Enumeration
I hypothesized that the WAF might only block known HTML tags. To test this, I injected a non-existent custom tag:
Payload:
Result: 200 OK. The server reflected the tag raw:
Phase 2: Event Enumeration
Since custom tags do not load external resources, standard events like onload or onerror do not fire. I needed an interaction event.
I fuzzed the custom tag for attributes: <test §event§=1>
I found that onfocus was allowed.
I had a working vector: <xss onfocus=alert(1)>.
However, a custom tag is just a text container. It cannot receive “focus” by default (unlike an input field), and I could not rely on the victim clicking it manually. I needed to chain three browser behaviour to weaponise this:
tabindex=”1”: This attribute forces the browser to treat the custom tag as an interactive, focusable element (allowing it to receive focus).
id=”x”: This gives the element a targetable identity.
URL Fragment (#x): Appending #x to the URL forces the browser to automatically scroll to and focus on the element with id=”x” immediately upon page load.
The trigger logic: Load Page -> Browser reads #x -> Jumps to
I initially attempted to use an <iframe> to deliver the payload invisibly.
Result: Failed
Root Cause: Modern browsers implement Focus Hijacking Prevention. They block elements inside a cross-origin <iframe> from receiving focus unless the user is already interacting with that frame.
To bypass this security control, I switched to a Top-Level Navigation attack. I used window.location to redirect the victim’s entire tab to the malicious URL. This makes the lab the “Active Window,” allowing the focus event to fire automatically.
I constructed the following JavaScript for the Exploit Server body:
<script>
location = '[https://YOUR-LAB-ID.web-security-academy.net/?search=%3Cxss+id%3Dx+onfocus%3Dalert%28document.cookie%29%20tabindex=1%3E#x](https://YOUR-LAB-ID.web-security-academy.net/?search=%3Cxss+id%3Dx+onfocus%3Dalert%28document.cookie%29%20tabindex=1%3E#x)';
</script>
Breakdown:
I pasted the script into the Exploit Server.
I clicked “Deliver exploit to victim”.
The victim visited my page, was immediately redirected to the lab, and the browser’s focus behaviour triggered the alert(document. cookie) popup.