CodePark/ questions / XSS: sources, sinks & sanitizing
START PRACTICINGPRACTICE
Frontend question · Frontend security › XSS: sources, sinks & sanitizing

React escapes values in JSX. Where can XSS still happen in a React app?

React escapes text you put in JSX. So <p>{comment}</p> shows <script> as plain text, and the browser never runs it. React also sets attribute values as strings, so a quote in a value can't break out of the attribute. But React can only protect the places it controls.

XSS can still happen in these places:

  • dangerouslySetInnerHTML: React inserts the string as real HTML, with no checks.
  • URL attributes: href, src, action and formAction accept javascript: URLs. React escapes the value, but the URL still runs when someone clicks it. Don't count on React to block these. Check the scheme yourself.
  • Direct DOM access: code like ref.current.innerHTML = html skips React completely.
  • Spreading props from data: <div {...userProps}> lets data from the server set dangerouslySetInnerHTML or other attributes.
  • Server rendering: state written into a <script> tag with plain JSON.stringify can break out of the tag.
  • Libraries: markdown renderers, chart tooltips and rich-text editors often use innerHTML inside.
  • eval and new Function on user data.

In short: React makes the default path safe. The escape hatches and the URL attributes are where you must sanitize or validate.

  • React escapes text and attribute values that you put in JSX.
  • dangerouslySetInnerHTML inserts raw HTML with no checks.
  • href and src can still run javascript: URLs, so check the scheme.
  • Refs with innerHTML, spread props from data and third-party libraries skip React's escaping.
  • Server-rendered state inside a <script> tag needs special escaping.