Frontend security basics
Defend browser surfaces against XSS, CSRF, unsafe dependencies, clickjacking, and accidental data exposure.

WHAT YOU WILL BE ABLE TO DO
Learning outcomes
- Explain frontend security basics in plain language.
- Connect the behavior to the underlying browser or framework model.
- Implement the core pattern and reason through edge cases.
- Answer common follow-ups without relying on memorized phrases.
01Explain it simply
Frontend security starts with treating all external data as untrusted and understanding which browser protections depend on response headers, cookie attributes, and safe rendering APIs.
One-line definition: Defend browser surfaces against XSS, CSRF, unsafe dependencies, clickjacking, and accidental data exposure.
02Mental model
XSS injects script into a trusted origin; CSRF causes a browser to send an authenticated request the user did not intend. They have different defenses: output encoding/CSP for XSS, and SameSite cookies plus CSRF tokens/origin validation for CSRF.
03Step by step
- Render text through framework escaping or textContent.
- Sanitize intentionally allowed HTML with a proven sanitizer.
- Deploy a restrictive Content Security Policy.
- Use Secure, HttpOnly, SameSite cookies where appropriate.
- Keep secrets and authorization decisions off the client.
04Working example
// Safe: input is treated as textmessage.textContent = untrustedValue;
// Dangerous without robust sanitizationmessage.innerHTML = untrustedValue;
// React also escapes text children by defaultreturn <p>{untrustedValue}</p>;Safe text sinks prevent markup from being interpreted. Rendering raw HTML creates an injection boundary that requires sanitization and a clear allowlist.
05Where it is used
- User-generated content
- Authentication and payments
- Third-party scripts
- Embedded content and admin tools
06Common mistakes
- Putting API keys in frontend environment variables
- Assuming client validation is authorization
- Using dangerouslySetInnerHTML with unsanitized content
- Storing sensitive tokens where injected scripts can read them
07Interview answer
Name the threat, trust boundary, attack path, and defense. Avoid saying the framework makes the application automatically secure.
Can a frontend application safely keep a secret API key?
No. Anything delivered to the browser can be inspected by the user or malicious code; secret-backed calls need a trusted server boundary.
DDConcept deep dives
Deep dive 1
Begin with assets, actors, and trust boundaries
Security review starts by naming what must be protected, who can provide input, and where data crosses from an untrusted source into a trusted capability. URL parameters, storage, API responses, user content, third-party scripts, postMessage, and DOM state are all input boundaries. A threat is concrete only when it identifies an attack path and impact.
- The browser is controlled by the user; client code cannot keep a secret from them.
- Authentication identifies a principal, while authorization checks permission for this resource and action.
- Client validation improves UX but never establishes server trust.
Deep dive 2
XSS is unsafe interpretation
XSS occurs when attacker-controlled data reaches a context that interprets it as active code or markup. React escapes normal text interpolation, but raw HTML, direct DOM sinks, unsafe URLs, compromised scripts, and server template mistakes reopen the boundary. Use safe text sinks by default; when rich HTML is necessary, sanitize with a maintained parser and narrow allowlist.
- Encoding is context-specific; HTML, attribute, URL, CSS, and JavaScript contexts differ.
- Sanitization decides which active markup is allowed and removes the rest.
- A strict nonce- or hash-based CSP limits impact but does not repair unsafe rendering.
// Safe: React renders text, not markup<p>{comment.body}</p>
// High-risk boundary: requires trusted sanitization<div dangerouslySetInnerHTML={{ __html: sanitizedHtml }} />The variable name sanitizedHtml is not proof. Its type and producer should make the trust transformation explicit, and the sanitizer policy must match the rendered context.
Deep dive 3
CSRF exploits ambient authority
When authentication cookies attach automatically, a malicious site may cause the browser to send a state-changing request even though it cannot read the response. SameSite cookies reduce cross-site attachment, while CSRF tokens and Origin validation prove the request came through an intended interaction. CORS read policy and CSRF request integrity are separate controls.
- Never perform state changes through GET.
- Use exact trusted origins when allowing credentialed CORS requests.
- High-risk operations may require recent reauthentication or transaction confirmation.
Deep dive 4
Token storage changes the threat trade-off
A token in localStorage is directly readable by any injected script in the origin. An HttpOnly cookie hides its value from JavaScript but the browser still sends it, requiring CSRF protections; injected same-origin code may still perform actions as the user. Reduce token lifetime, privilege, exposed surfaces, and third-party script trust rather than declaring one storage mechanism universally safe.
- Secure limits cookies to HTTPS and narrow Domain and Path reduce scope.
- Do not put secret service credentials in public environment variables or bundles.
- Rotate sessions and invalidate server-side authority when compromise is suspected.
Deep dive 5
Headers and dependency controls provide defense in depth
CSP frame-ancestors and X-Frame-Options address clickjacking, nosniff reduces MIME confusion, a careful Referrer-Policy limits URL leakage, and Permissions-Policy limits selected browser capabilities. Dependencies and runtime third-party scripts execute with substantial trust, so minimize them, pin and review updates, protect publishing accounts, and plan for compromise.
- Security headers must be tested on deployed responses, not only configured in source.
- Automated advisories find known issues but cannot establish safe architecture.
- postMessage receivers verify exact origin, expected source, and payload schema.
QAInterview questions and model answers
Attempt each answer aloud before opening it. The model answer shows the depth and precision expected in an interview; it is not a script to memorize.
Intermediate · Conceptual · 1 min · Question 1What is cross-site scripting?Open model answer
Model answer
XSS occurs when attacker-controlled data is interpreted as executable script or active markup within a trusted origin. Stored, reflected, and DOM-based labels describe delivery paths; the core failure is data crossing into an unsafe execution context without the correct encoding, sanitization, or policy.
Open question page →Intermediate · Conceptual · 1 min · Question 2How does React reduce XSS risk, and where are the escape hatches?Open model answer
Model answer
React escapes text children and attribute values by default, so ordinary interpolation is treated as text. Risk returns with dangerouslySetInnerHTML, unsafe URL handling, direct DOM sinks, third-party widgets, compromised dependencies, or server-rendered markup assembled unsafely.
Open question page →Intermediate · Conceptual · 1 min · Question 3What is the difference between encoding and sanitization?Open model answer
Model answer
Context-aware output encoding makes data inert in a specific sink. Sanitization parses intentionally allowed HTML and removes disallowed elements, attributes, and URL schemes. A sanitizer must be maintained and configured for the intended context; regex is not an HTML sanitizer.
Open question page →Intermediate · Conceptual · 1 min · Question 4What does a Content Security Policy provide?Open model answer
Model answer
CSP restricts which scripts and other resources a document may execute or load. A strict nonce- or hash-based script policy reduces the impact of injection, while report-only deployment helps discover violations. CSP is defense in depth, not permission to keep unsafe rendering.
Open question page →Intermediate · Conceptual · 1 min · Question 5What is CSRF?Open model answer
Model answer
CSRF causes a browser to send an authenticated state-changing request that the user did not intend, usually because cookies are attached automatically. Defenses include SameSite cookies, unpredictable CSRF tokens, and Origin or Referer validation; state-changing GET requests remain a design flaw.
Open question page →Intermediate · Conceptual · 1 min · Question 6Why does CORS not prevent CSRF?Open model answer
Model answer
CORS primarily controls whether another origin's JavaScript may read a response. Browsers can send many cross-origin requests without CORS read permission, so cookie-authenticated state changes still require CSRF defenses.
Open question page →Intermediate · Conceptual · 1 min · Question 7What cookie attributes matter for authentication?Open model answer
Model answer
Secure limits transmission to HTTPS, HttpOnly prevents JavaScript access, and SameSite controls cross-site attachment. Narrow Domain and Path scope, short lifetimes, rotation, and server-side validation also matter. HttpOnly mitigates token theft through XSS but does not stop an injected script from making same-origin requests.
Open question page →Intermediate · Conceptual · 1 min · Question 8Should authentication tokens be stored in localStorage?Open model answer
Model answer
There is no universal answer, but localStorage is readable by any script executing in the origin, so XSS can steal persistent tokens. HttpOnly secure cookies reduce direct token theft but require CSRF design. The architecture should minimize token exposure, lifetime, and privilege.
Open question page →Intermediate · Conceptual · 1 min · Question 9Can a frontend safely contain a secret API key?Open model answer
Model answer
No. Anything delivered to the browser can be inspected or invoked by the user or malicious code. Public identifiers may live in the client, but secret-backed operations require a trusted server that enforces authentication, authorization, quotas, and allowed parameters.
Open question page →Intermediate · Conceptual · 1 min · Question 10How do you defend against clickjacking?Open model answer
Model answer
Prevent untrusted sites from framing sensitive pages with CSP frame-ancestors and, for legacy coverage, X-Frame-Options. For intended embeds, allowlist exact ancestors and design high-risk confirmations so UI redressing cannot silently trigger them.
Open question page →Intermediate · Conceptual · 1 min · Question 11What is supply-chain risk in frontend applications?Open model answer
Model answer
Build dependencies and third-party scripts execute with significant trust. Pin and review updates, minimize dependencies, use lockfiles and automated advisories, protect publishing credentials, restrict runtime third parties with CSP, and maintain an incident response path. An audit command alone is not a complete program.
Open question page →Advanced · Conceptual · 1 min · Question 12What is DOM clobbering?Open model answer
Model answer
Named HTML elements can create or shadow properties on document and other host objects, causing code to read attacker-created elements instead of expected values. Avoid implicit named access, query explicitly, validate types, and keep unsafe HTML out of the document.
Open question page →Intermediate · Conceptual · 1 min · Question 13How should postMessage be used securely?Open model answer
Model answer
Send to an exact targetOrigin rather than *, and on receipt verify event.origin and, where relevant, event.source. Validate the message schema and treat payloads as untrusted. Origin checking without payload validation is insufficient.
Open question page →Intermediate · Conceptual · 1 min · Question 14What is the frontend's role in authorization?Open model answer
Model answer
The UI may hide unavailable actions for usability, but the server must authorize every sensitive request using trusted identity and resource context. Client route guards, disabled buttons, and hidden fields are not security boundaries.
Open question page →Intermediate · Conceptual · 1 min · Question 15How would you review a feature that renders user-authored rich text?Open model answer
Model answer
Define the allowed formatting model, sanitize on a trusted boundary with a maintained allowlist, sanitize or encode again for the actual sink as appropriate, restrict URLs and embeds, deploy CSP, test mutation and parser edge cases, and avoid allowing arbitrary style or script-capable markup.
Open question page →SCScenario questions
Scenario 1
A comments feature renders server-provided HTML using dangerouslySetInnerHTML. Review the risk and propose a safe design.
- Identify whether rich HTML is genuinely required.
- Trace every producer and transformation of the value.
- Use plain text when possible; otherwise sanitize with a maintained allowlist.
- Restrict URLs, embeds, and styles, then add a strict CSP.
- Test stored, reflected, and DOM mutation paths.
Reveal worked answer
If comments only need text, render them as React text children and format structure from a constrained data model. If rich text is required, accept a small documented syntax, sanitize on the server and at the rendering boundary where needed, store provenance, and never trust previously stored content merely because it came from the database. CSP limits impact but does not replace sanitization.
Scenario 2
A cookie-authenticated transfer endpoint accepts POST requests with no CSRF token and allows a permissive CORS origin.
- Confirm cookie SameSite attributes and whether credentials are accepted cross-origin.
- Require a non-simple authenticated request with a CSRF token or robust origin validation.
- Allowlist exact trusted origins and never reflect arbitrary origins with credentials.
- Ensure GET is read-only and reauthenticate high-risk actions.
Reveal worked answer
I would treat CORS and CSRF as separate controls. The endpoint validates authorization and an anti-CSRF signal, checks Origin for browser requests, uses an appropriate SameSite cookie, and permits credentials only for exact trusted origins. A malicious origin must neither read sensitive responses nor cause an authenticated state change.