Temple pillars with holographic data — XSS across 30 injection contexts

XSS Masterclass: 30 Labs, Every Context, Every Bypass

Complete XSS attack playbook from 30 PortSwigger labs — reflected, stored, DOM, WAF bypasses, CSP bypasses, AngularJS escapes, and exploitation chains.

This is everything I learned from completing 30 PortSwigger Web Security Academy XSS labs — distilled into a single reference you can use during real bug bounty hunting. No theory padding. Every section has the payload, the context it works in, and when you'd use it on a real target.

Reflected XSS by Injection Context

The key question: where does your input appear in the response?

HTML Body (No Encoding)

The simplest case. Your input lands directly in the HTML body with no filtering. Payload: <script>alert(document.domain)</script>. Always start with this — legacy apps, admin panels, and internal tools are often this easy.

HTML Attribute Context

Angle brackets are encoded, but you're inside an attribute value. Payload: " autofocus onfocus="alert(document.domain). This breaks out of the attribute and injects an event handler. Autofocus ensures it fires without user interaction.

JavaScript String Context

When angle brackets are encoded: '-alert(document.domain)-' breaks the string using subtraction operator. When quote AND backslash are escaped: </script><script>alert(1)</script> closes the script tag entirely. When single quote is escaped with backslash: \'-alert(1)// escapes the escape character.

Template Literal Context

Inside backticks: ${alert(document.domain)} — template literals support expression interpolation. Increasingly common in modern JS apps.

WAF Bypass Techniques

This is where real bug bounty value lives. Most tags blocked? Use <body onresize> via iframe. All standard tags blocked? Custom tag: <xss autofocus tabindex=1 onfocus=alert(1)>. Only SVG allowed? <svg><animatetransform onbegin=alert(1)>. The approach: fuzz all HTML tags, find which pass through, fuzz event handlers, build payload from allowed combinations.

DOM XSS Sinks

DOM XSS happens entirely in the browser. Key sinks: innerHTML (use <img onerror> not <script>), jQuery .attr(href) accepts javascript: protocol, jQuery selector $() creates DOM elements from HTML strings, AngularJS expressions with ng-app allow constructor chain execution. Always search JS source for these dangerous sinks.

CSP Bypass Checklist

unsafe-inline = inline scripts work. Whitelisted CDN = host payload on CDN. JSONP on whitelisted domain = callback=alert. Missing base-uri = <base href> injection. Dangling markup = exfil data via unclosed img src. Always check the CSP header — missing base-uri is surprisingly common.

Exploitation Chains

Finding XSS is step one. Proving impact is what gets you paid. Cookie theft (if no HttpOnly flag), password capture via autofill on injected login forms, and CSRF token bypass — XSS on the same origin defeats ALL CSRF protections. Always demonstrate maximum impact in your report.

Bug Bounty Recon Checklist

  • Search boxes — URL params reflected in page
  • Profile fields — name, bio, website (stored XSS goldmine)
  • JS source — search for innerHTML, $()
  • AngularJS — check for ng-app in HTML
  • CSP header — curl -I target.com
  • Blind XSS — inject in support tickets, feedback forms

Built from 30 PortSwigger Web Security Academy labs. Each technique tested and verified. Use responsibly on authorized targets only.

No comments yet