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

A server renders the page with this code. state includes each user's bio. Why can this cause XSS?

const html = `
  <script>
    window.__STATE__ = ${JSON.stringify(state)};
  </script>`;
A bio containing </script><script>alert(1)</script> ends the script block early, because JSON.stringify doesn't escape <

The HTML parser runs before the JavaScript parser. It sees </script> inside the string and closes the script block there. The rest of the bio then becomes new HTML, including a new <script> tag. Fix it by escaping < as \u003c in the JSON, or use a library like serialize-javascript. Frameworks like Next.js already do this for their own data.

"JSON strings are always quoted" is the tempting wrong answer. The quotes only matter to JavaScript, and the HTML parser doesn't know about them. "
JSON.stringify runs functions" is wrong, because it skips functions.