0

I've observed that React can HTML encode specific characters to prevent XSS vulnerabilities in certain contexts. For instance, consider the following code in App.jsx:

function App() {
    const XSSProblematicChars = "><'\"()&:`";

    return (
        <>
            <h4>Displayed: {XSSProblematicChars}</h4>
            <img src={XSSProblematicChars}/>
        </>
    );
}

The corresponding HTML output would be:

<h4>Displayed: &gt;&lt;'"()&amp;:`</h4>
<img src="><'&quot;()&amp;:`">

As demonstrated, HTML encoding varies depending on the context. For instance:

  1. In the h4 element, <, >, and & characters are encoded.
  2. In the src attribute of the img element, " and & characters are encoded.

However, it's important to note that this encoding alone may not provide comprehensive protection against XSS attacks. To illustrate, consider the following App.jsx code. If the anchor element is clicked, the document's content can be altered using an XSS payload:

function App() {
    const XSSPayload =
        "javascript:eval(atob('ZG9jdW1lbnQuYm9keS5pbm5lckhUTUw9JzxoMSBzdHlsZT0idGV4dC1hbGlnbjogY2VudGVyOyBwb3NpdGlvbjogYWJzb2x1dGU7IHRvcDogNTAlOyBsZWZ0OiA1MCU7IHRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIC01MCUpOyI+ISEhIEhBQ0tFRCAhISE8L2gxPic7'))";

    return (
        <>
            <a href={XSSPayload}>Click Me to Trigger XSS</a>
        </>
    );
}

This occurs because React fails to HTML encode the : character, allowing the use of javascript: syntax to trigger XSS.

To address this issue, I aim to create a function that will HTML encode all problematic characters in user input displayed on the frontend. Are there any other characters, like :, that React might have overlooked when encoding for HTML output?

1 Answer 1

0

React does not protect against XSS when using JSX data binding syntax ({}) in HTML attributes [1].

For HTML, the recommendation is to do this:

import purify from "dompurify";
<div dangerouslySetInnerHTML={{ __html:purify.sanitize(data) }} />

I would recommend to use DOMPurify and not try to develop your own solution if you don't have a good reason for it.

If you still want to develop your own solution, [2] describes a safe way of encoding HTML Attributes:

HTML Attribute Encoding Encoding Mechanism: Encode all characters with the HTML Entity &#xHH; format, including spaces, where HH represents the hexadecimal value of the character in Unicode. For example, A becomes A. All alphanumeric characters (letters A to Z, a to z, and digits 0 to 9) remain unencoded.

Even if you do so, there are HTML attributes (e.g. onClick) where it is dangerous to inject user provided data. They are listed in [3] too.

[1] https://snyk.io/blog/10-react-security-best-practices/
[2] https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html#output-encoding-rules-summary
[3] https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html#output-encoding-for-html-attribute-contexts

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .