Reputation: 11828
I'm currently using this answer to escape my HTML before inserting it into a <div>
using dangerouslySetInnerHTML
in my app.
However, I noticed there are also libraries like DOMPurify, which purport to be the safer approach to escaping HTML. Except that it's approximately 1000x larger of a solution, so I'm wondering if it's necessary.
I notice that the first solution in my answer seems to work well enough. I tried entering <script>alert('a')</script>
into the message box and it seemed to be escaped properly. For my purposes I'm only doing a couple simple markup transformations (bolding, italics, etc.).
Is what I'm doing enough, or do I need a more powerful solution like DOMPurify? I rather not add the dependency if it's not necessary.
Upvotes: 5
Views: 2641
Reputation: 213
In its basic form? Yes, it is safe when used like this:
<p id="example"></p>
<script>
let escapedText = escapeHtml(userInput);
document.getElementById("example").innerHTML = escapedText;
</script>
However, once you start modifying the escaped text and adding your own HTML tags to it, you may accidentally introduce a vector to XSS. Here is an example with a link specified by user input:
<p id="example"></p>
<script>
let escapedLink = escapeHtml(userInput);
document.getElementById("example").innerHTML = `<a href="${escapedLink}">Click here</a>`;
</script>
This demonstrates two shortcomings:
The attacker could set the link to javascript:alert(1)
and achieve XSS.
Legitimate links could not be inserted, as the HTML escape blocks the /
character.
This is a simple example and there are many less obvious ways to mess up badly here. Using a good HTML purifier library, such as DOMPurify, not only helps against XSS and similar vulnerabilities, but also lets you implement or even accept user input for custom HTML.
Upvotes: 2