← ClaudeAtlas

client-securitylisted

Client-side security for React apps — XSS sinks, secrets in the bundle, token storage, CSP, redirects, postMessage, and the limits of client-side enforcement. Load when handling untrusted data, credentials, or third-party code.
soumit-kaz/lazysitter · ★ 1 · Code & Development · score 72
Install: claude install-skill soumit-kaz/lazysitter
# Client-side security Two questions cover most of it: 1. **What did we ship to the browser that we should not have?** 2. **What will we render that we do not control?** ## Everything in the bundle is public There is no such thing as a secret in client code. Minification is not obfuscation, and source maps are often shipped. **Build-time public prefixes are the trap**: `NEXT_PUBLIC_`, `VITE_`, `REACT_APP_`, `PUBLIC_`, `EXPO_PUBLIC_`, `GATSBY_`. A value behind one of these is **inlined into the JavaScript as a string literal** — it is not an environment variable at runtime, it is published. ```bash lazysitter fe-index signals --rule SEC-PUBLIC-ENV-SECRET ``` Some keys are *designed* to be public — a Stripe publishable key, a Supabase anon key, a public analytics id. Say which is which, and why, rather than flagging everything or nothing. ## XSS: React escapes by default, and here is where it does not React escaping text is why XSS is rare in React apps — and why the exceptions matter so much. **`dangerouslySetInnerHTML`** — the main sink. Every use needs a real sanitizer (DOMPurify or equivalent) with a stated allow-list, and a reason the content cannot be rendered as text. Sanitize on **output**, not only on input — data can enter through a path you did not sanitize. **`href` / `src` from a variable** — a `javascript:` or `data:text/html` URL is script execution: ```jsx <a href={user.website}> // user.website = "javascript:fetch('/api/keys')..." ``` Validat