React dangerouslySetInnerHTML should not be used

ID

javascript.react_dangerously_set_innerhtml

Severity

high

Resource

Risky Values

Language

JavaScript

Tags

CWE:79, OWASP:2021:A3, PCI-DSS:6.5.4, React

Description

dangerouslySetInnerHTML is React’s replacement for using innerHTML in the browser DOM. In general, setting HTML from code is risky because it’s easy to inadvertently expose your users to a cross-site scripting (XSS) attack.

Rationale

Improper use of the innerHTML can open you up to a cross-site scripting (XSS) attack. Sanitizing user input for display is notoriously error-prone, and failure to properly sanitize is one of the leading causes of web vulnerabilities on the internet.

Our design philosophy is that it should be "easy" to make things safe, and developers should explicitly state their intent when performing “unsafe” operations. The prop name `dangerouslySetInnerHTML` is intentionally chosen to be frightening, and the prop value (an object instead of a string) can be used to indicate sanitized data.

After fully understanding the security ramifications and properly sanitizing the data, create a new object containing only the key __html and your sanitized data as the value.
function MyComponent() {
  const title = response.from.backend.title;
  // FLAW: vulnerable to potential XSS attack
  return <div dangerouslySetInnerHTML={{__html: title}} />;
}

This detector simply reports any usage of the dangerouslySetInnerHTML property that it is not sanitized using a sanitizer() abstraction. Note that other detectors, such as the Cross-Site Scripting detector for JavaScript also checks if the value passed to dangerouslySetInnerHTML could be injected from untrusted input.

Remediation

To fix this issue, remove the dangerouslySetInnerHTML property from the component if possible. If you cannot remove it, make sure that the value passed to dangerouslySetInnerHTML is sanitized, using a sanitizer() function to abstract your chosen sanitizer.

import dompurify from 'dompurify';

function MyComponent() {
  const title = response.from.backend.title;
  const sanitizer = dompurify.sanitize;
  // FLAW: vulnerable to potential XSS attack
  return <div dangerouslySetInnerHTML={{__html: sanitizer(title)}} />;
}

Some recommended anti-XSS sanitizers can be chosen among the following libraries:

  • DOMPurify - XSS sanitizer for HTML, MathML and SVG.

  • xss - Sanitize untrusted HTML (to prevent XSS) with a configuration specified by a Whitelist.

  • xss-filters - Secure XSS Filters.

Configuration

You may configure the accepted sanitizer functions changing the sanitizers property, a list of regular expressions for the names that will be accepted as sanitizer functions.

References