Category:
Web ApplicationSummary:
How cross-site scripting injects attacker JavaScript into a victim's browser to steal sessions — reflected, stored, and DOM, plus detection and prevention.Cross-site scripting (XSS) happens when an app places untrusted input into a page without context-correct encoding, so the input runs as script in the victim’s browser instead of staying inert text. It’s the same injection family as SQL injection — data reinterpreted as code — and it’s frequently chained with CSRF to fire requests, or with IDOR to reach another user’s data once a session is stolen.
Common Techniques
- Reflected — payload in the request (URL, form field) is echoed straight back in the response.
- Stored — payload is saved server-side (comment, profile field) and served to every later visitor.
- DOM-based — client-side script writes untrusted input into the DOM via a sink like
innerHTMLordangerouslySetInnerHTML, no server round-trip needed. - Filter / WAF bypass — alternate encodings, case tricks, and event-handler attributes to slip past naive sanitizers.
- Session-cookie theft & request-riding — a working payload exfiltrates cookies or issues authenticated requests as the victim.
Want to save time on reporting?
Let PentestPad generate, track, and export your reports - automatically.

Testing
Inject a unique marker into every reflected and stored field, then check whether it renders as HTML or comes back encoded:
<img src=x onerror=alert(1)>Try it in URL params, form fields, headers, and JSON body values; combine manual probing with a DAST scan and a CSP report-only policy to catch what you miss. Log every sink that fired — with the exact payload and context — so it lands in the pentest report instead of a browser tab you’ll forget to screenshot.
Remediation
Apply context-aware output encoding — HTML, attribute, JS, and URL contexts each need different escaping. Set a strict Content-Security-Policy to blunt whatever slips through, and mark session cookies HttpOnly so script can’t read them even after a successful injection. Lean on your framework’s auto-escaping (React, Vue, etc.) and don’t defeat it with raw-HTML sinks; treat input validation as defense-in-depth, not the primary control.