DEV Community

Cover image for Why You should avoid dangerouslySetInnerHTML in React?
Prateek Lohani
Prateek Lohani

Posted on

Why You should avoid dangerouslySetInnerHTML in React?

The dangerouslySetInnerHTML in React allows developers to directly set the innerHTML property of an element without any sanitization. Passing untrusted user input into the attribute is risky and can lead to serious security vulnerabilities like Cross-Site-Scripting (XSS).
So, It is always the best choice to avoid passing untrusted user input to the dangerouslySetInnerHTML attribute.
If passing user input is absolutely necessary, ensure that the input is sanitized.

Usage -

import React, { useEffect, useRef } from "react";

const sanitizeHTML = (html) => {
    // Only run in browser environment
    if (typeof window === 'undefined') return html;

    try {
        const parser = new DOMParser();
        const doc = parser.parseFromString(html, "text/html");

        // Define all the allowed tags to use 
        const allowedTags = ["p"];

        const sanitizeNode = (node) => {
            if (node.nodeType === Node.ELEMENT_NODE) {
                const element = node;

                // Process children first
                Array.from(element.childNodes).forEach((child) => sanitizeNode(child));

                if (!allowedTags.includes(element.tagName.toLowerCase())) {
                    // Replace element with its children
                    while (element.firstChild) {
                        element.parentNode.insertBefore(element.firstChild, element);
                    }
                    element.remove();
                }
            }
        };

        sanitizeNode(doc.body);
        return doc.body.innerHTML;
    } catch (error) {
        console.error('Error sanitizing HTML:', error);
        return html; // Return original content if sanitization fails
    }
};

const SanitizeContent = ({ content }) => {
    const ref = useRef(null);

    useEffect(() => {
        if (ref.current) {
            const sanitized = sanitizeHTML(content);
            ref.current.innerHTML = sanitized;
        }
    }, [content]);

    return <div ref={ref} />;  
};

const App = () => {
    const item = '<p>This is the sample !</p>'
    return (
        <>
            <SanitizeContent content={item} />
        </>
    );
};

export default App;
Enter fullscreen mode Exit fullscreen mode

Top comments (0)