What's dangerous about dangerouslySetInnerHtml?

I've been working on a side project in which I need to dynamically set the inner HTML of a react component based on some text. To do this, I need to use React's dangerouslySetInnerHTML attribute.

Interested in whether my usage of this attribute would be a cause for concern, I researched what risks are involved in using it. Why is it dangerous?

React's documentation on this attribute graciously lets us know that:

setting HTML from code is risky because it's easy to inadvertently expose your users to a cross-site scripting (XSS) attack.

So what exactly does this mean? And when is it safe to use?

When dangerouslySetInnerHTML is set on a React element, some content is injected into the DOM. It's that content the determines whether or not you're in danger of exposing your users to XSS attacks.

The main case that needs careful consideration is when that content can be defined by a potentially malicious user.

Dangerous case

Consider for example a comment system. You may be tempted to allow users to leave comments which include HTML tags to allow them to style their messages. You could achieve this by storing their comment in a database, loading it any time a user views the comment, and rendering it to the page via dangerouslySetInnerHTML. This is dangerous because someone could leave a comment which contains a script tag that reads things like session tokens and passes them off to be abused. When some other user loads the page, fetches the comment, and sets the inner HTML dangerously, the script tag will be placed onto the page and executed.

If you still want to do something like this, then you'll need to look into sanitising your data first.

Safe case

It's perfectly safe to use dangerouslySetInnerHTML when the content of the HTML can't be set by an unknown third party. If, for example, you only use HTML that is generated by your client, then you don't have to worry about XSS attacks. Fortunately, this is what I'm using it for in my project.

Note on naming

This investigation also upholds the value of naming an attribute in this way. Including "dangerous" in the attribute name itself set me on a path of education which resulted in me being appropriately confident in the security of my users' machines.