PortSwigger-Writeups

Lab: Reflected XSS into HTML context with most tags and attributes blocked

Difficulty: Practioner

Vulnerability: Reflected XSS with WAF Evasion

Lab Link: https://portswigger.net/web-security/cross-site-scripting/contexts/lab-html-context-with-most-tags-and-attributes-blocked

1. The Goal

The objective of this lab was to execute a Cross-Site Scripting (XSS) attack in a search function protected by a strict Web Application Firewall (WAF).

My goal was to identify a single allowed HTML tag and a compatible event handler, then bypass the need for user interaction to execute the print() function automatically.

2. Reconnaissance (Fuzzing)

I started by testing standard XSS vectors (

a1

To find a bypass, I used Burp Suite Intruder to fuzz for allowed tags.

Phase 1: Tag Enumeration

  1. I intercepted the search request: GET /?search=<§test§>
  2. I loaded the standard PortSwigger XSS Cheat Sheet tag list.
  3. I analysed the response. Most returned 400, but one tag returned
  4. 200 OK and was reflected raw: <body>

a2 a3 a5

Phase 2: Attribute Enumeration Next, I needed an event handler compatible with the <body> tag.

  1. I configured the payload position: GET /?search=<body+§event§=1>
  2. I loaded the Events list.
  3. I found that the onresize event returned 200 OK.

a6 a7

3. Code Analysis (The Constraint)

I had a working vector: <body onresize=print()>.

However, the onresize event only fires when the browser window changes dimensions. I could not rely on a victim manually resizing their browser. I needed a delivery mechanism to force this interaction.

4. The Exploit Strategy

I chose to use the Exploit Server to host an iframe attack.

The Logic:

  1. Trap: Load the vulnerable lab page inside an iframe on my exploit page.
  2. Trigger: Use JavaScript on my page (onload) to programmatically change the width of the iframe.
  3. Execution: The browser inside the iframe detects the size change, fires the onresize event (from my injected <body> tag), and executes the payload.

a8

5. The Payload

I constructed the following HTML for the Exploit Server body:

<iframe src="[https://YOUR-LAB-ID.web-security-academy.net/?search=%3Cbody%20onresize=print()%3E](https://YOUR-LAB-ID.web-security-academy.net/?search=%3Cbody%20onresize=print()%3E)"
        onload="this.style.width='100px'">
</iframe>

a9

Note: I URL-encoded the payload (%3C, %3E) to ensure the iframe src attribute remained valid.

6. Execution
  1. I pasted the payload into the Exploit Server.
  2. I clicked “Deliver exploit to victim.”
  3. The victim visited my page, the iframe loaded, resizing itself, and the print() function executed automatically.