Skip to content

Cross-Site Scripting (XSS)

Cross-Site Scripting (XSS) is a class of vulnerabilities where untrusted input is interpreted by a browser as executable code, typically JavaScript. Instead of treating user data as text, the browser parses it as part of the page’s DOM, HTML, or script context. This allows an attacker to execute code in the victim’s browser under the origin of the vulnerable site.

The impact is not limited to alerts and popups. XSS enables session theft, credential exfiltration, CSRF token bypass, UI redressing, malware delivery, and lateral movement within a web application. Because execution happens in the victim’s browser, the attack bypasses many server-side controls.

At its core, XSS is a failure to properly separate code from data at rendering boundaries.

Glossary

Origin

Scheme + host + port. Determines browser security boundaries.

DOM (Document Object Model)

In-memory representation of a web page manipulated by JavaScript.

Sink

A function or location where untrusted data is rendered or executed (e.g., innerHTML, eval, attribute injection).

Source

Where attacker-controlled input originates (URL params, headers, form fields, API responses).

Context

Where data is inserted: HTML body, attribute, URL, JS string, CSS, etc.

Encoding / Escaping

Transforming characters so they are interpreted as data rather than code.

Sanitization

Removing or rewriting dangerous constructs from input.

Content Security Policy (CSP)

Browser policy restricting which scripts and resources may execute.

XSS Types

Stored XSS

Payload is persisted on the server (database, cache, logs) and served to multiple users. Impact is high because exploitation is automatic and scalable. Typical sources: comments, profile fields, CMS content.

Reflected XSS

Payload is reflected directly from request to response. Requires victim interaction (clicking a crafted link). Common in search pages, error messages, redirects.

DOM-Based XSS

Injection happens entirely in client-side JavaScript. Server response may be clean while frontend logic creates the vulnerability. Often overlooked by backend-focused teams.

How XSS Actually Happens (Mental Model)

  • Attacker controls some input.
  • Application places that input into a browser execution context.
  • Browser interprets it as executable code instead of text.
  • Code executes with the site’s origin privileges.

Key observation: The browser decides execution, not the server.

Security must align with browser parsing rules, not just backend validation.

Contexts and Why They Matter

Different contexts require different protections.

HTML body

<div>USER_INPUT</div>

Needs HTML escaping (<, >, &, ”, ’).

HTML attribute

<img src="USER_INPUT">

Requires attribute escaping and URL validation.

JavaScript string

var name = "USER_INPUT";

Requires JS string escaping or safe serialization.

URL / href

<a href="USER_INPUT">

Must block javascript: and dangerous schemes.

CSS

background: url(USER_INPUT);

Rare but exploitable in legacy browsers.

Incorrect encoding in the wrong context creates bypasses.

Common Dangerous Sinks

  • innerHTML, outerHTML
  • document.write
  • eval, setTimeout(string)
  • jQuery .html()
  • React dangerouslySetInnerHTML
  • Attribute concatenation
  • Template rendering without escaping

Rule: Treat every sink as hostile until proven safe.

Mitigation Strategies (Defense in Depth)

Context-Aware Output Encoding

Encode at the last moment, in the correct context. Never reuse encoding across contexts. Prefer framework-provided escaping.

Avoid Dangerous APIs

Use textContent instead of innerHTML. Avoid string-based code execution entirely.

Input Validation (Secondary)

Validate format and length. Do not rely on validation as the primary defense.

Content Security Policy (CSP)

Block inline scripts and restrict sources. Use CSP as damage containment, not a substitute for escaping.

Framework Hygiene

Understand your framework’s escaping guarantees. Avoid disabling protections for convenience.

Bypass Techniques to Understand (Attacker Mindset)

  • Context breaking ("><script>)
  • Event handler injection (onerror=...)
  • URL scheme abuse (javascript:)
  • HTML entity tricks
  • UTF-7 / encoding edge cases (legacy)
  • DOM clobbering
  • CSP bypass via misconfiguration
  • Mutation XSS (browser rewriting)

Studying bypasses teaches where defenses fail.

Testing and Detection Techniques

  • Manual payload crafting in each context.
  • Browser devtools DOM inspection.
  • Fuzzing sinks with known payloads.
  • Security linters and static analysis.
  • CSP violation reports.
  • Automated scanners (useful but incomplete).

Always verify in real browsers.

Real-World Impact Patterns

  • Session cookie theft → account takeover.
  • Token exfiltration from SPA storage.
  • Silent API abuse as victim.
  • Credential harvesting overlays.
  • Supply-chain injection via admin panels.

XSS often becomes a stepping stone, not the final exploit.

Engineering Takeaways

  • XSS is a rendering bug, not just an input bug.
  • Context awareness is non-negotiable.
  • Framework defaults help but do not eliminate risk.
  • CSP limits damage but cannot fix logic flaws.
  • Always reason from browser behavior, not server intent.