VibeSecurity

Security check

Cross-site scripting (XSS) in React and Next.js apps

React escapes text by default, which removes the most common XSS. The remaining risk sits where code opts out of that protection or puts untrusted data somewhere React does not sanitise.

By the VibeSecurity team1 min read

The usual openings

  • dangerouslySetInnerHTML with content from users, a CMS or an AI model.
  • Markdown rendered to HTML without sanitising.
  • A link whose href comes from user input, which allows javascript: URLs.
  • Libraries or embed widgets that write to innerHTML.

Sanitise before you render

React with DOMPurify
import DOMPurify from 'dompurify';

const clean = DOMPurify.sanitize(userHtml);
return <div dangerouslySetInnerHTML={{ __html: clean }} />;

Limit the damage

  • Keep session tokens in HttpOnly cookies so injected script cannot read them.
  • Add a Content-Security-Policy that restricts script sources. Start in report-only mode.
  • Avoid storing long-lived secrets in localStorage.

Frequently asked questions

Is my React app immune to XSS?

No. Rendering text is safe, but raw HTML rendering, unvalidated links and third-party scripts can still be exploited.

Does a CSP replace sanitising?

No. A CSP reduces the impact of an injection. Sanitising prevents it. Use both.

Sources

  1. 1.OWASP Cross Site Scripting Prevention Cheat Sheet
  2. 2.MDN: Content Security Policy