A ref with innerHTML skips React's protection
The first line, this would have run, is the proof: the browser parsed the string, created an img, failed to load x and ran the onerror attribute as code. A real attacker would put something harmful there. The textContent version shows the same string as plain text.
XSS happens when text from someone else is treated as code in your page. JSX escapes every string you put in text or attributes, so it always shows as text, but refs with innerHTML, dangerouslySetInnerHTML, unsafe URLs, spread props and server-rendered state can still let it in.
Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.
Ready for more? This phase has 5 hands-on exercises with automatic checks.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
A component shows a search term from the URL: div.innerHTML = 'Results for ' + q. Rewrite it safely in React.
Write a small helper serializeState(obj) that is safe to put inside <script type="application/json">, and show how the client reads it back.
Write a component that shows a user's name in bold inside a sentence ("Welcome back, Asha!") without using any HTML strings.
Explain it without notes
What is XSS, and what can an attacker do once their script runs in your page?
Exactly why is <p>{userText}</p> safe in React, both in the browser and in server rendering?
List the ways XSS can still get into a React app.
Why is putting JSON.stringify(data) inside a <script> tag dangerous, and how do you fix it?
Preview
Console
Nothing logged yet.Expected console output
this would have run
img inside .safe: 0
img inside .unsafe: 1