When does text become running code?
innerHTML parses a string into elements. In the isolated demo, an image error handler runs code; textContent displays the same string as text.
React text children are appropriate for plain text. Rich HTML needs a maintained sanitizer and an explicit policy. This one sink is not a complete security audit.
Understand it. Then fix it.
innerHTML creates HTML elements.
HTML means HyperText Markup Language. InnerHTML tells the browser to read the string as HTML. If someone controls that string, they can include an element with an event handler.
// Harmless local test string:
`<img src="/missing-image"
onerror="window.demo = 1">`The image fails. The handler runs.
In this local test, the image fails to load. Its error handler runs and sets our demo number to one. Cross-site scripting, or XSS, is when untrusted input becomes code in your page.
Then write text. Not HTML.
Use textContent. With the same input, the browser shows the characters instead of creating an image. No image is created, so its error handler cannot run.
output.textContent = query;React text works for this case too.
In React, put the string inside braces as a text child. Raw HTML is different. If you really need rich text, use a maintained HTML sanitizer with rules for what you allow.
// Plain text in React:
<p>{query}</p>Code blocks are teaching excerpts. Keep the surrounding error handling and application requirements.
Save the code excerpts ↓Read the full transcript
I show a search query on my page. How can a string make the browser run code? HTML means HyperText Markup Language. InnerHTML tells the browser to read the string as HTML. If someone controls that string, they can include an element with an event handler. In this local test, the image fails to load. Its error handler runs and sets our demo number to one. Cross-site scripting, or XSS, is when untrusted input becomes code in your page. But I only wanted to show what the person searched for. I do not need any HTML. Use textContent. With the same input, the browser shows the characters instead of creating an image. No image is created, so its error handler cannot run. In React, put the string inside braces as a text child. Raw HTML is different. If you really need rich text, use a maintained HTML sanitizer with rules for what you allow. I asked the user for a search term. Apparently, I also hired them to write our JavaScript.