Learn › Cross-Site Scripting (XSS)

Cross-Site Scripting (XSS)

Free PortSwigger Web Security Academy walkthroughs for Cross-Site Scripting (XSS) — each with a clear explanation and a runnable solution script. All labs on GitHub.

PortSwiggerApprentice
Reflected XSS into HTML context with nothing encoded
Cross-site scripting is the vulnerability class that makes "don't trust the client" a rule instead of a suggestion — every reflected XSS bug ultimately...
PortSwiggerApprentice
Stored XSS into HTML context with nothing encoded
Stored XSS is the more dangerous sibling of reflected XSS for a simple reason: the payload doesn't need a victim to click a crafted link, it just needs...
PortSwiggerApprentice
DOM XSS in document.write sink using source location.search
DOM-based XSS breaks the mental model the first two labs built up: there is no server-side reflection to find, because the vulnerable data flow happens...
PortSwiggerApprentice
DOM XSS in innerHTML sink using source location.search
This lab looks almost identical to the previous one on the surface — the same location.search source, the same search box, the same absence of any...
PortSwiggerApprentice
DOM XSS in jQuery anchor href attribute sink using location.search source
Every DOM XSS lab so far has involved raw HTML injection — breaking out of an attribute or supplying an event handler that the browser parses as...
PortSwiggerApprentice
DOM XSS in jQuery selector sink using a hashchange event
Every DOM sink so far has fired on page load, triggered by a query parameter we could put straight in a URL and send to a victim as a link. This lab...
PortSwiggerApprentice
Reflected XSS into attribute with angle brackets HTML-encoded
The first reflected lab in this series had no encoding at all, so a plain <script> tag was enough. This lab adds the first real defense we've seen:...
PortSwiggerApprentice
Stored XSS into anchor href attribute with double quotes HTML-encoded
This lab combines two things we'd only seen separately until now: a stored injection point (the comment form's "website" field, rather than a one-shot...
PortSwiggerApprentice
Reflected XSS into a JavaScript string with angle brackets HTML encoded
This lab moves the injection point somewhere new: inside a JavaScript string literal embedded directly in the page, rather than in HTML markup or an...

Want to go from zero to junior pentester?

These walkthroughs are a taste. The full path — live, hands-on, small cohorts — starts with a free webinar.

Join the Free Live Webinar →