Engineering

Trust-Breaking Mistakes We Still See in Modern Websites

The avoidable decisions that weaken trust in modern websites and products — from unsafe content handling to over-trusting the front end.

Ritvik SinghUpdated Jul 19, 20264 min read
Abstract React security warning composition

Modern frameworks solve a lot, but they do not remove responsibility. We still see websites that look polished on the surface and break trust underneath because the wrong layer is trusted, the wrong content is allowed through, or important decisions are left to the browser.

dangerouslySetInnerHTML is still dangerous

The API name is honest. If you inject HTML from CMS content, markdown, or rich text, sanitize on the server with a maintained library and a strict allowlist. Client-only sanitization is better than nothing — and worse than a server pass attackers cannot skip.

// Avoid unless the HTML is sanitized upstream
<article
  dangerouslySetInnerHTML={{ __html: unsanitizedCmsHtml }}
/>

Tokens in localStorage

Storing session tokens in localStorage is convenient for SPAs and convenient for XSS. Prefer httpOnly, secure cookies with careful CSRF strategy — or a well-reviewed auth library that already made those tradeoffs.

Trusting the client for authorization

Hiding an admin route in the React router is not authorization. Every privileged action needs a server check. Assume the attacker can call your API directly with a modified JSON body — because they can.

  • Never take role or price solely from the client payload.
  • Re-fetch permissions server-side for sensitive views.
  • Log authorization failures; patterns reveal probing.

URL state and open redirects

React apps love query params for deep links. Validate them. A returnUrl that accepts //evil.example is an open redirect with your brand in the first half of the address bar.

Dependency hypnosis

Installing a hook to solve a five-line problem can import a tree you never reviewed. Prefer small, known packages for security-sensitive paths — auth, crypto, HTML parsing — and pin versions deliberately.

The most expensive npm install is the one that silently expands your attack surface.

React did not make security obsolete. It changed where mistakes hide. Review the escapes, the storage, and the server — that is where modern apps actually fail.