Skip to main content

Security

Encoding

React by default encodes almost all data values when creating DOM elements.

To provide users with an escape hatch to insert HTML content into the DOM, React is equipped with the eloquently-named function dangerouslySetInnerHTML(), clearly conveying the dangers of using it.

DON'T: Use the method dangerouslySetInnerHTML()

Handled by Users

Contexts that are unattended by the React security model and are handled by the users include creating:

  • HTML anchor (link) elements with user- provided input as the source for the href attribute value.

    • This mostly applies to versions prior to the recently released React v16.9 which mitigates javascript:-based URLs in href attribute values and other contexts such as form actions, iFrame sources, and others.

      data:text/html,
      <a href="javascript: alert('hello from javascript!')">click me</a>
  • React components from user-provided input

  • React’s server-side rendering could potentially introduce XSS vulnerabilities if malicious user input is injected as-is to a JavaScript context without being properly encoded or sanitized.

    let data = {
    username: "pwned",
    bio: "</script><script>alert('XSS Vulnerability!')</script>"
    }

    <script>window.__STATE__ = ${JSON.stringify({ data })}</script>

What to look for in a Code Review

  1. Look for dangerouslySetInnerHTML being called.

  2. Can users add links that other users may click on? If so, try adding a ‘link’ like this:

    javascript: alert('You are vulnerable to XSS!');

    If the alert pops up on the page, you have an XSS vulnerability. Try everywhere these custom links are loaded. Most likely, not every instance will be vulnerable.

  3. Look for JSON.stringify() being called with a variable that may have un-trusted data inside a script tag.

Reference