I'm making a TV guide with React. I'm pulling show information from this API: http://api.tvmaze.com/episodes/333
As you can see the summary
contains html. If I render the field. then the HTML is interpreted as a string, meaning that you can see the <p>
tags, etc., on the page.
I know that I could use dangerouslySetInnerHTML
but it's discouraged for security reasons. What is the best practice for this? It must be fairly common to get formatted text from an API and need to render it. I'm surprised there isn't a filter which would allow <p>
, <h1>
, etc., but not script tags.
According to the official documentation, dangerouslySetInnerHTML is React's replacement for using innerHTML in the browser DOM. This means that if in React if you have to set HTML programmatically or from an external source, you would have to use dangerouslySetInnerHTML instead of traditional innerHTML in Javascript.
React renders HTML to the web page by using a function called ReactDOM. render() .
When to use dangerouslySetInnerHTML. A use case where you need to set the HTML content of a DOM element is when you populate a <div> element with the data coming from a rich text editor. Imagine you have a webpage where people can submit comments and you allow them to use a rich text editor.
Dynamically rendering benign HTML code in React requires the use of dangerouslySetInnerHTML . That is not a naming mistake. This property is dangerous, and using it carelessly will create XSS vulnerabilities in your application.
Is dangerouslySetInnerHTML the only way to render HTML from an API in React?
Technically, no. You could do some magic with the Babel transformer if you prefer, but that approach isn't any more "safe" or recommendable. It's only a more flexible alternative. See here for more info about that.
That said, dangerouslySetInnerHTML
is still the recommended approach to inserting raw markup into your component. Make no mistake, the name is frightening just to remind developers of the potential XSS risk. The fact that you use it doesn't automatically render your code "smelly" or otherwise "bad".
In other words, if you are certain that the code you fetch is not malicious it's a pretty safe bet. If you trust the API you have little to worry about. For example, this is perfectly safe:
return <div dangerouslySetInnerHTML={{__html: "<p>foo bar</p>"}} />;
and so is this:
let markup = SomeApiCallToTrustedProvider(); //"<p>foo bar</p>"
return <div dangerouslySetInnerHTML={{__html: markup}} />;
I'm no expert in this field, but my understanding is that if users cannot influence the presentation of your website for other users, you are safe from the traditional XSS attacks. An example would be if you were to fetch un-sanitized input data from a database and reflect it as raw markup in your code. That would allow a malicious user to submit code to the database, which when presented to other users, would then be executed effectively giving users the ability to manipulate your page.
I'm surprised there isn't a filter which would allow
<p>
,<h1>
etc but not script tags.
Well, this would be some kind of sanitization. There are snippets out there of how you can implement your own, here for example...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With