ReactDOM.findDOMNode() should not be used

ID

javascript.react_find_dom

Severity

high

Resource

Risky Values

Language

JavaScript

Tags

CWE:242, React

Description

The function findDOMNode from package react-dom is an "escape hatch" used to access the underlying DOM node in React. In most cases, use of this function is discouraged because it pierces the component abstraction.

It has been deprecated in StrictMode. Its usage is discouraged and, possibly, it will be deleted in a future version.

Rationale

Avoid using ReactDOM.findDOMNode() (and direct access to the DOM) to avoid security issues, like cross-site scripting vulnerabilities, where React components provide a safer alternative. Skipping the React component layer and directly accessing the DOM node skips the protection provided by React against cross-site scripting attacks.

The following code is a call on ReactDom.findDOMNode():

import React, { Component } from "react";
import ReactDOM from "react-dom";
import ChildComponent from "./child-component";
= Code injection with javascript: URL in JSX
:icons: font

[cols="1,3" width="60%" frame="none" grid="rows" stripes="odd" .toc]
|===
|ID
| javascript.react_javascript_url
|Severity
| [red]#high#
|Resource
| Injection
|Language
| JavaScript
|===

== Description



== Rationale

[source,javascript]
== Remediation

[source,javascript]
== Configuration

The detector has no specific configurable parameters.

== References

- https://cwe.mitre.org/data/definitions/94.html[CWE-94] : Improper Control of Generation of Code ('Code Injection').

- OWASP Top 10 2021 - https://owasp.org/Top10/A03_2021-Injection/[A03 : Injection].

class MyComponent extends Component {

  componentDidMount() {
    // FLAW
    const node = ReactDOM.findDOMNode(this);
    // ... use DOM node ...
  }

  render () {
    return <ChildComponent>{this.props.children}</ChildComponent>;
  }
}

Remediation

It is recommended to add a ref to the element we want to reference (which should be a DOM HTML element, possibly wrapping a React component; or, alternatively, pass a ref to the custom component and pass that along to the DOM using ref forwarding via React.forwardRef().

This post explains how to replace findDOMNode with safer alternatives: Getting rid of findDOMNode in your React application

In the example above, instead of working directly on the DOM node, use ref on a wrapper DOM element:

import React, { createRef, Component } from "react";
import ChildComponent from "./child-component";

class MyComponent extends Component {

  componentDidMount() {
    // Do not use ReactDOM.findDOMNode(). Use ref on a wrapper DOM element
    const node = this.wrapper.current;
    // ... use DOM node ...
  }

  wrapper = createRef();

  render () {
    return (
      <div ref={this.wrapper}>
        <ChildComponent>{this.props.children}</ChildComponent>
      </div>
    );
  }
}

Configuration

No specific configuration is available.

References