Command Palette

Search for a command to run...

Hectal
Phase 21Advanced22 of 28 in React

Security in React Apps

Defend React apps: how JSX escaping stops XSS, safe HTML and URLs, secrets and tokens in the browser, securing Server Functions, CSP and dependency hygiene.

Security means making sure your app does only what you meant it to do, even when someone sends it strange input on purpose. A React app runs in the browser of every visitor, talks to servers, shows text that other people wrote and pulls in hundreds of packages written by strangers. Each of those is a door. This phase walks through every door in a React app, one at a time: what the threat is in plain words, how React already protects you, where that protection stops, how to close the gap and how to verify that it is closed.

You'll start with XSS (cross-site scripting, when someone else's text runs as code in your page) and why JSX blocks most of it by default. Then the escape hatches where it gets back in: dangerouslySetInnerHTML, refs, unsafe URLs, spread props and server-rendered state. After that come the things the browser can't keep secret (API keys, tokens), how to store login state, CSRF, how Server Functions and Server Components change the picture, and finally the supply chain: npm audit, lockfiles, Content Security Policy and Subresource Integrity.

Everything here is defensive. When an example needs untrusted input it uses a harmless stand-in that only writes to the console (this would have run), so you can see a dangerous sink execute and then watch the fix stop it. Every live example runs real React 19.2 in your browser, and the exercises check that your fixes really hold.

0/6 · 0%
6 topics ~3 h 22 code blocks & diagrams
Start with the first topic
1
21.1

How React Protects You from XSS

XSS happens when text from someone else is treated as code in your page. JSX escapes every string you put in text or attributes, so it always shows as text, but refs with innerHTML, dangerouslySetInnerHTML, unsafe URLs, spread props and server-rendered state can still let it in.

29 min 3 code practice

2
21.2

dangerouslySetInnerHTML and Sanitising HTML

dangerouslySetInnerHTML puts a string into the page as real HTML, so any untrusted HTML must pass through a sanitiser such as DOMPurify first; better still, render Markdown and rich content as React elements, and let Trusted Types enforce the rule.

32 min 4 code practice

3
21.3

Unsafe URLs and Attributes

A URL can carry code (javascript:), point somewhere harmful, or hand your page to another tab. React 19 blocks javascript: URLs, but you still validate user URLs with new URL and a protocol allow-list, add rel="noopener noreferrer" to new-tab links, and never spread untrusted objects into props.

28 min 3 code practice

4
21.4

Secrets, Tokens and Auth in the Browser

Everything shipped to the browser can be read by anyone, so secrets stay on servers; VITE_ and NEXT_PUBLIC_ variables are public by design. Store login sessions where scripts can't read them (httpOnly cookies), defend cookies against CSRF with SameSite, Origin checks and tokens, and treat auth state in React as a display hint the server always re-checks.

33 min 4 code practice

5
21.5

Securing Server Components and Actions

A Server Function ("use server") is a public HTTP endpoint that anyone can call with any arguments, so each one must validate its input, check who is calling and whether they may touch this record, and return only what the UI needs; and Server Components must pass Client Components only the fields they need, with the taint APIs as an experimental safety net.

33 min 4 code practice

6
21.6

Dependencies, CSP and Supply Chain Hygiene

Most of your app's code was written by strangers, so keep dependencies few, locked and audited (npm audit, lockfiles, npm ci, pinning, controlled install scripts), and add browser-enforced walls: a Content Security Policy that only runs your own scripts, and Subresource Integrity for anything loaded from a CDN.

31 min 4 code practice

Practise this phase

Hands-on exercises: write the code, see your page live, and press Check to have it tested automatically.