Cross-Site Scripting (XSS)
Cross-site scripting is injection into the browser: attacker-controlled input is reflected into a page without proper encoding, so the victim's browser runs the attacker's JavaScript in the context of the trusted site. That script can steal session cookies, act as the user, or rewrite the page — turning Meridian's own app against its users.
This topic covers the three XSS types, why output encoding (not input filtering) is the fix, and how Content Security Policy backstops it when an encoding bug slips through.
The Mechanism
Data that should be displayed as text is instead interpreted as HTML or JavaScript, because it was not encoded for the HTML context. The browser cannot tell the injected script from the site's own — both arrive in the trusted page — so it runs with the site's full trust, including access to the user's session. XSS is the app failing to keep user data as data when it renders it.
Stored, Reflected, and DOM-Based
Stored XSS persists — a malicious comment served to every viewer. Reflected XSS bounces off a parameter in a crafted link the victim clicks. DOM-based XSS happens entirely client-side, when JavaScript writes untrusted data into the page. Each needs the same encoding discipline, just in a different place — server-side for the first two, in the client code for the third.
The Fix: Context-Aware Output Encoding
Encode data for the exact context it lands in — HTML body, attribute, JavaScript, URL — because the same value that is safe in one context is dangerous in another. Modern frameworks auto-encode by default, and the bugs appear where developers bypass that: innerHTML, dangerouslySetInnerHTML, a template marked |safe. The rule is to let the framework encode and never hand it raw HTML built from user input.
What XSS Buys the Attacker, and CSP
XSS enables session hijacking if the cookie is not HttpOnly, performing actions as the victim, in-page credential phishing, and keylogging — which is why the Chapter 3 cookie flags and this chapter reinforce each other. A strict Content Security Policy restricts what scripts can run and where they can send data, containing XSS even when an encoding bug slips through. CSP is a backstop, not a substitute for encoding.
Output encoding — encode at the moment data enters a page, for that page's context; correct because the same data may be safe in one context and dangerous in another.
Input sanitization — strip "dangerous" markup on the way in; it loses information, breaks legitimate content, and misses context-specific cases. Encode on output; sanitize input only for rich text, with a vetted library like DOMPurify.
- Building HTML by concatenating untrusted input or using
innerHTML/dangerouslySetInnerHTML, bypassing the framework's auto-encoding. - Filtering input for
<script>and assuming XSS is handled, when dozens of contexts and encodings evade naive filters. - Storing session tokens in JavaScript-reachable places (missing
HttpOnly), so any XSS immediately steals sessions. - Shipping no Content Security Policy, so a single encoding slip becomes full script execution with no containment.
- Treating DOM-based XSS as impossible because the server encodes output, when the flaw is in client-side JavaScript.
- Rely on a framework that auto-encodes by context and never bypass it; where raw HTML is needed, sanitize with a vetted library.
- Encode output for the specific sink — HTML, attribute, JavaScript, URL — treating each context as distinct.
- Set
HttpOnly,Secure, andSameSiteon session cookies so XSS cannot trivially steal them (Chapter 3). - Deploy a strict Content Security Policy as defense in depth and monitor its violation reports.
- Handle DOM-based XSS by encoding in client code and avoiding unsafe sinks like
innerHTML.
Knowledge Check
Why does output encoding fix XSS better than filtering input for <script> tags?
- Data safe in one context is unsafe in another; encode by sink
- Input filtering is far too slow for busy, high-traffic websites
- Encoding removes the need to authenticate users
- Filtering <script> tags catches every possible XSS payload
What distinguishes DOM-based XSS from stored and reflected XSS?
- It happens client-side when JS writes untrusted data
- It requires the attacker to have a valid database account
- It only affects sites without HTTPS
- It is the only XSS type that cannot steal cookies
What role does a Content Security Policy play against XSS?
- A backstop limiting what scripts run and where data goes
- It is the primary fix, replacing the need to encode output
- It encrypts the page so scripts cannot read it
- It blocks all JavaScript on the site unconditionally
You got correct