THN Interview Prep

Web Security, CORS & XSS

Frontend security is not only backend concern passed through headers. Browser code handles untrusted data, credentials, third-party scripts, cross-origin requests, storage, redirects, and user-visible trust boundaries. Senior frontend engineers know which defenses belong in the browser and which must be enforced server-side.

Core details

ThreatCore ideaPrimary defenses
XSSAttacker runs script in your originescaping, safe sinks, sanitization, CSP, Trusted Types
CSRFBrowser sends credentials on unwanted requestSameSite cookies, CSRF tokens, origin checks, idempotency
CORS mistakeWrong cross-origin read permissionsnarrow Access-Control-Allow-Origin, credentials discipline
Token theftSecrets exposed to JS or third-party scriptHttpOnly cookies, short-lived tokens, least privilege
ClickjackingSite embedded and tricked into clicksframe-ancestors / X-Frame-Options
Supply chain scriptThird-party code runs with page privilegereview, CSP, sandboxing, consent gating, kill switches

XSS classes:

  • Stored: malicious content saved and later rendered to many users.
  • Reflected: malicious input echoed immediately in a response.
  • DOM-based: client JavaScript reads attacker-controlled data and writes to an unsafe DOM sink.

React escapes text by default, but it does not make unsafe sinks safe. dangerouslySetInnerHTML, direct DOM writes, third-party widgets, Markdown/HTML rendering, and URL construction still require explicit review.

Content Security Policy: CSP limits what the browser may execute or load. Use nonces or hashes for scripts, avoid broad unsafe-inline, and set frame-ancestors for embed policy. CSP is defense-in-depth, not a replacement for output encoding.

Trusted Types: where supported and practical, Trusted Types can restrict dangerous DOM sinks so only approved sanitization policies create HTML/script URLs.

CORS: controls whether another origin may read a response. It is not an auth system. A server must still authenticate and authorize the request. Avoid reflecting arbitrary origins, especially with credentials.

CSRF: if authentication relies on cookies, the browser may attach them automatically. SameSite cookies help, but sensitive writes should also validate method, origin, token, and idempotency where appropriate.

Understanding

The browser origin model protects reads, not all sends. A malicious site may be able to cause a form POST or image request, but CORS decides whether its JavaScript can read the response. That is why CORS misconfiguration is dangerous but does not replace server authorization.

XSS is severe because script running in your origin can read the DOM, call APIs as the user, manipulate UI, exfiltrate non-HttpOnly tokens, and tamper with business flows. The strongest defense is to avoid creating executable markup from untrusted input. When rich HTML is a product requirement, sanitize with an allowlist and keep the sanitizer policy versioned and tested.

Storage choices are security choices. Local storage is easy but readable by injected script. HttpOnly cookies reduce token theft from XSS but require CSRF controls and careful SameSite/Secure settings. There is no universal best storage choice without the auth model and threat model.

Practical examples

Unsafe DOM sink:

preview.innerHTML = userProvidedMarkdown;

Safer shape:

preview.textContent = userProvidedText;

If product requires HTML, sanitize and constrain the allowed elements/attributes.

CORS with credentials should name the exact origin:

Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true
Vary: Origin

Do not combine credentialed requests with wildcard origin policy.

Cookie baseline for session auth:

Set-Cookie: session=...; HttpOnly; Secure; SameSite=Lax; Path=/

Use SameSite=Strict where product flows permit it, and explicit CSRF tokens for higher-risk writes.

Senior understanding

ProbeStrong answer
“React prevents XSS?”React escapes text, but unsafe sinks and HTML rendering remain dangerous
“Fix CORS?”Identify caller origin, credentials need, allowed methods/headers, and auth checks
“Where store token?”Compare XSS exposure, CSRF exposure, refresh flow, and logout/revocation
“Third-party tag?”Consent, CSP, sandboxing, performance budget, data access, and kill switch

Failure modes

  • Using dangerouslySetInnerHTML with untrusted content.
  • Reflecting request Origin into Access-Control-Allow-Origin without an allowlist.
  • Treating a successful CORS preflight as proof of authorization.
  • Storing long-lived access tokens in local storage for a high-risk app.
  • Adding CSP in report-only mode and never enforcing or reviewing reports.
  • Sending validation errors that include raw unsanitized user input.

Diagram

Loading diagram…

See also

Spotted something unclear or wrong on this page?

On this page