Why does the React.js API warn you to embed raw HTML?
From tutorial
But there's a problem! Our comments made look like this browser: "
<p>This is <em>another</em> comment</p>". We want those tags to be rendered as HTML.This will protect you from an XSS attack. There is a way to get around it, but the structure warns you not to use it:
...
<span dangerouslySetInnerHTML={{__html: rawMarkup}} />This is a special API that deliberately makes it difficult to embed raw HTML, but we will use this backdoor to showcase it.
Remember: using this feature, you rely on Showdown for security.
Thus, there is an API for embedding raw HTML, but the method name and documents all warn of this. Is it safe to use? For example, I have a chat application that accepts Markdown comments and converts them into HTML strings. HTML snippets are generated on the server by the Markdown converter. I trust the converter, but I'm not sure if there is a way for the user to carefully handle Markdown to use XSS. Is there anything else I should do to make sure it is safe?
Most Markdown processors (and I believe Showdown also) allow the writer to use embedded HTML. For example, a user may enter:
This is _markdown_ with a <marquee>ghost from the past</marquee>. Or even **worse**: <script> alert("spam"); </script> As such, you should have a white list of tags and cut out all the other tags after converting from markdown to html. Only then use the aptly named dangerouslySetInnerHTML .
Note that this also does stackoverflow. The above Markdown looks like this (without your warning in your face):
This is a markdown with a ghost from the past. Or even worse :
warning ("spam");
There are three reasons why html is best avoided:
- security risks (xss, etc.)
- performance
- event listeners
Security risks are greatly mitigated by markdowns, but you still need to decide what you consider valid and ensure that it is prohibited (for example, you do not allow images, for example).
A performance issue is important only when something changes in the markup. For example, if you created html with this: "Time: <b>" + new Date() + "</b>" . The reaction usually only decides to update the textContent of the <b/> element, but instead replaces everything and the browser needs to re-process the html. In large chunks of html this is more of a problem.
If you want to know when someone clicks on a link in the results, you have lost the ability to do this simply. You will need to add the onClick listener to the nearest responsive node and find out which element was clicked by delegating actions from there.
If you want to use Markdown in React, I recommend a pure rendering handler, for example. vjeux / markdown-react .