API & BACKEND ARCHITECTURE / SYSTEM CONCEPT BRIEF

Cross-site scripting (XSS)

Cross-site scripting (XSS) happens when an attacker gets their JavaScript to run in other users' browsers on your site.

IntermediatePhase 02 / Topic 20 of 20RequirementsTrade-offsFailure modes
01

Overview

Cross-site scripting (XSS) happens when an attacker gets their JavaScript to run in other users' browsers on your site. Because the script runs with your site's origin, it can read page data, act as the user, steal tokens stored in JavaScript-accessible storage, or deface the page. The three types are stored XSS (malicious input saved and shown to others, like a comment), reflected XSS (input echoed from the URL into the response), and DOM-based XSS (client-side code writing untrusted data into the page).

The core defense is context-aware output encoding, meaning untrusted data is always rendered as text, never as HTML or script. Modern frameworks like React escape by default; risk returns with escape hatches (dangerouslySetInnerHTML, innerHTML, v-html), URLs like javascript:, and inline event handlers. Content Security Policy (CSP), HttpOnly cookies, and HTML sanitizers add defense in depth.

A notice board

If the building lets anyone pin notes, a malicious note could say "security says: hand your keys to the person in the red jacket." Encoding is laminating every note so it is read as a note, not treated as an official instruction.

02

When to use it

  • Any page that displays user-provided content.
  • Rich text editors, comments, profiles, markdown rendering.
  • Security reviews of front-end code.
03

Where it shows up in interviews

Rendering user content safely

Recognize it when: user text shown to other users.

  • Design a comments system
  • Design a social profile page
  • Design a markdown-based wiki
04

Where it is used in real software

Samy worm (MySpace, 2005)

A stored XSS payload added over a million friends in a day, showing how XSS can spread virally.

React and Angular

Escape interpolated values by default; security bugs usually come from bypassing that with raw HTML APIs.

Content Security Policy

Google, GitHub, and others deploy strict CSP to block inline and unauthorized scripts even if an injection slips through.

05

Key terms

Stored XSS
Payload persisted and served to other users.
Reflected XSS
Payload in a request echoed back in the response.
DOM XSS
Client-side code inserts untrusted data into the DOM unsafely.
Output encoding
Converting characters like < and " into safe entities for the context.
CSP
Header restricting which scripts and resources the page may load or run.
06

How it works, step by step

  1. 1
    Treat all user data as untrusted

    Including data from your own database, since it may have been stored by an attacker.

  2. 2
    Render as text by default

    Use framework interpolation or textContent, never innerHTML for untrusted data.

  3. 3
    Sanitize when HTML is required

    Use a proven sanitizer (DOMPurify) with an allow-list of tags and attributes.

  4. 4
    Validate URLs

    Allow only http(s) and relative links; block javascript: and data: URLs in href and src.

  5. 5
    Add defense in depth

    Strict CSP with nonces, HttpOnly and SameSite cookies, and security headers.

Stored XSS attack
Step 1 / 4
Attacker
Comment API
Database
Victim browser

STEP 1The attacker posts a comment containing a script tag.

07

Unsafe vs safe rendering

Displaying a user comment

Step 1 / 5
ApproachPayload shown asSafe?
element.innerHTML = commentExecuting HTML and scriptNo
element.textContent = commentLiteral textYes
React: <p>{comment}</p>Escaped textYes
React: dangerouslySetInnerHTML={{ __html: comment }}HTMLOnly after sanitizing
<a href={userUrl}> with javascript: URLScript on clickNo; validate the scheme

NOWApproach: element.innerHTML = comment | Payload shown as: Executing HTML and script | Safe?: No

The default text rendering is safe; each escape hatch needs sanitization or validation.

08

Implementation

import DOMPurify from "dompurify"; // Safe by default: React escapes interpolated stringsfunction Comment({ author, body }: { author: string; body: string }) {  return <p><strong>{author}</strong>: {body}</p>;} // Rich text: sanitize with an allow-list before rendering HTMLfunction RichComment({ html }: { html: string }) {  const clean = DOMPurify.sanitize(html, { ALLOWED_TAGS: ["b", "i", "em", "strong", "a", "ul", "li", "p"], ALLOWED_ATTR: ["href"] });  return <div dangerouslySetInnerHTML={{ __html: clean }} />;} // Links: allow only safe schemesfunction SafeLink({ href, children }: { href: string; children: React.ReactNode }) {  const ok = /^(https?:\/\/|\/(?!\/))/i.test(href);  return ok ? <a href={href} rel="noopener noreferrer">{children}</a> : <span>{children}</span>;}
09

Complexity and performance

Encoding costO(length)

Negligible.

Impact if exploitedFull account takeover

Script acts as the victim on your site.

10

Trade-offs

Rich content vs safety

Allowing HTML enables formatting but requires careful sanitization; Markdown with a safe renderer is often a better compromise.

Strict CSP vs compatibility

Strict CSP blocks most XSS but can break third-party scripts and inline code; roll out in report-only mode first.

11

Variants and related techniques

Trusted Types

Browser API that forces DOM sinks like innerHTML to accept only vetted values.

Sandboxed iframes

Render untrusted HTML in an isolated origin.

12

Common mistakes

  • Sanitizing on input only.

    Fix: Encode on output for the specific context; data may be used in many contexts later.

  • Storing auth tokens in localStorage.

    Fix: Any XSS can read them; prefer HttpOnly cookies with SameSite and CSRF protection.

  • Trusting framework escaping in attribute URLs.

    Fix: Validate URL schemes; escaping does not stop javascript: links.

13

Interview questions

What are the types of XSS and how do you prevent them?

Stored, reflected, and DOM-based. Prevent them by rendering untrusted data as text with context-aware encoding (framework defaults), sanitizing any allowed HTML with an allow-list, validating URLs, avoiding dangerous DOM APIs, and adding CSP and HttpOnly cookies as defense in depth.

Does React prevent all XSS?

React escapes interpolated values, which prevents most XSS, but dangerouslySetInnerHTML, unsafe href values like javascript: URLs, and direct DOM manipulation can still introduce it.

14

Practice problems

ProblemDifficultyWhat it trains
Find and fix XSS in a comments componentEasySafe rendering.
Design safe rich-text comments with MarkdownMediumSanitization and CSP.