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.
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.
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.
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.