JavaScript, React, Security

One request, full server access: Inside the React2Shell vulnerability

by Lucas Jordan
One Request, Full Server Access: Inside the React2Shell Vulnerability

The recently disclosed React2Shell (CVE-2025-55182) vulnerability represents a critical security flaw affecting certain React-based applications that improperly handle user-controlled input in server-side execution contexts. This vulnerability can allow attackers to escalate from client-side manipulation to remote command execution (RCE) on backend systems.

In this post, we’ll break down:

  • What React2Shell is
  • How this critical vulnerability works
  • The risks and real-world impact
  • How to identify if you’re vulnerable
  • How to protect your applications

What is React2Shell?

The React2Shell vulnerability is a critical security flaw discovered in late 2025 that affects React Server Components (RSC), which is used extensively in modern web applications and frameworks. It enables an attacker to achieve unauthenticated RCE which can allow an attacker to take over a web server without needing a username or password. In affected environments, attackers can pivot from manipulating React-controlled data to executing system-level commands, hence the name “React2Shell.”

How the vulnerability works

The vulnerability lies in how React decodes payloads sent to React Server Function (aka Server Actions) endpoints from a user’s browser. If the server doesn’t properly check the data it receives before “translating” it into instructions, an attacker can send a single, specially crafted message that tricks the server into running malicious code. This flaw is particularly dangerous because it happens “pre-authentication” meaning the attack hits the server’s internal logic before your app even has a chance to ask for a login.

Example attack flow

  1. An attacker submits malicious input via a React frontend (URL parameters, form fields, JSON payloads, etc).
  2. The backend improperly concatenates that input into:
    • A system command
    • A template engine
    • A dynamic evaluation function
  3. The malicious payload executes on the server.
React2Shell
React2Shell flow

Risks and real-world impact

While the root cause of the React2Shell vulnerability lies at the code-level, the real-world impact can be severe.

After the React2Shell vulnerability was publicly disclosed, real-world exploitation attempts were reported from a wide range of threat actors.

Through the exploitation this vulnerability attacker we able to use varying attack vectors to gain control of systems such as SQL injection and cross-site scripting (XSS).

Through use of this exploit attackers were then able to execute arbitrary commands to perform database exfiltration, add new malicious users, install reverse shells, add backdoors, and even add cryptocurrency miners to the affected servers.

In affected applications the attackers were able to use system details and environment variables to gain access to cloud credentials. The theft of these credentials could then be used to move laterally to other cloud resources making other systems vulnerable to attack.

Evidence of real-world exploitation

Security researchers and threat-intelligence teams have observed active exploitation in the wild:

How to identify if you are vulnerable

Even if your app does not implement any React Server Function endpoints it may still be vulnerable if your app supports React Server Components.

The React2Shell vulnerability exists in React Server Components versions:

  • 19.0.0,
  • 19.1.0,
  • 19.1.1,
  • 19.2.0

The vulnerability is also present in the following packages (same version numbers):

Several popular React frameworks and bundlers also included the vulnerable React packages either directly or through peer dependencies. The following React frameworks & bundlers are affected: next, react-router, waku, @parcel/rsc, @vitejs/plugin-rsc, and rwsdk.

If your application code does not use a server, your application is not affected by this vulnerability.
Likewise if your application does not use any of the above listed frameworks bundlers or packages, your application is not affected by this vulnerability

How to protect your applications

If your application is using any of the affected packages listed above it is recommended that you upgrade affected packages to their latest versions immediately.

When deploying patched versions it is also a good idea to rebuild your containers to ensure these are no cached versions of potentially vulnerable versions remaining in the affected environment.

Continue to monitor the situation:

  • Enable WAF (web application firewall) alerts in affected environments,
  • Review logs for suspicious outbound connections, child process creation, SSR runtime errors & input validation failures.

Remain vigilant, check for any unexpected shell processes, modified application files, new system users, creation of hidden directories, unexpected spikes in CPU usage all of which could be indicators of a security breach.

Adopt a security first mindset to development

Even if your application is not susceptible to the React2Shell vulnerability there are practices you should always follow when building any application to protect from security threats.

Never trust user input

For all web applications the most critical security requirements is proper user input validation and handling. Without proper validation and sanitation every form field, URL query parameter or request response could be weaponised against you.

JSX automatic string escaping

Fortunately in React we are able to utilise “automatic string escaping” inside our JSX components. What this means is any user input rendered inside {} in JSX will have any potentially dangerous characters converted to their safe HTML entity equivalents.

dangerouslySetInnerHTML

Sometimes as developers we want to render HTML code coming from untrusted sources (user input, for example). The easiest way to render it in a browser is to directly assign it to the inner HTML attribute. However this property unlike JSX automatic string escaping potentially exposes our web applications to XSS vulnerabilities. React limits its use by the dangerouslySetInnerHTML property but rather than making its usage secure this property simply warns the developer against its usage. Always sanitise dynamic input assigned to the dangerouslySetInnerHTML property. Libraries such as DOMPurify can be leveraged to achieve this.

Direct rendering of raw HTML in general is discouraged.

Secure URL parameters and links

URLs are a common attack vector. Rendering of URLs from user input whether as a href or src value is another scenario where we are not protected by JSX automatic string escaping. Always validate and sanitise URLs before using them.

Validate and sanitise URL as re-usable react hook

JavaScript
import { useMemo } from "react";

export function useSafeUrl(input, fallback = "https://my-host.com") {
  return useMemo(() => {
    const original = input;

    if (!input || typeof input !== "string") {
      return {
        url: fallback,
        isValid: false,
        original,
      };
    }

    const trimmed = input.trim();

    try {
      const url = new URL(trimmed);

      const isValidProtocol = url.protocol === "http:" || url.protocol === "https:";

      if (!isValidProtocol) {
        throw new Error("Invalid protocol");
      }

      return {
        url: url.href,
        isValid: true,
        original,
      };
    } catch {
      return {
        url: fallback,
        isValid: false,
        original,
      };
    }
  }, [input, fallback]);
}

Example usage:

JavaScript
export function Link({ href, label }) {
  const { url, isValid } = useSafeUrl(href);

  return (
    <div>
      <a
        href={url}
        target="_blank"
        rel="noopener noreferrer"
        aria-invalid={!isValid}
      >
        {label}
      </a>

      {!isValid && (
        <p style={{ color: "red" }}>
          The provided URL was malformed.
        </p>
      )}
    </div>
  );
}

URLs should also be validated and sanitised in your backend to protect against Open Redirect vulnerabilities.

JavaScript
export function Link({ href, label }) {
  const { url, isValid } = useSafeUrl(href);

  return (
    <div>
      <a
        href={url}
        target="_blank"
        rel="noopener noreferrer"
        aria-invalid={!isValid}
      >
        {label}
      </a>

      {!isValid && (
        <p style={{ color: "red" }}>
          The provided URL was malformed.
        </p>
      )}
    </div>
  );
}

Sanitise and validate form input

To ensure form data is safe to use in you web application or any system it is important to validate and sanitise form input.

When handling form input you should:

  • Restrict form fields to a specific type
  • Replace potentially dangerous characters (<, >, &, ', ", etc) with their HTML entity equivalents
  • Whitelist acceptable patterns
  • Limit input length
  • Leverage popular libraries to assist you (Joi, Zod, Yup)

Sanitise API requests

Prior to making API requests it is important to validate and sanitise any user input that forms part of the request. This includes not only the request body but also request query or search parameters which could be manipulated by malicious actors.

Before making API requests:

  • Validate and sanitise form data
  • Type check, validate and sanitise request body to conform to API requirements
  • Validate and sanitise request parameters

Content Security Policy (CSP) integration

For an added layer of security for your application consider integrating a Content Security Policy. When well implemented CSP additionally protects against XSS attacks.

Dynamically evaluated input

Usage of exec, spawn, eval, new Function when combined with user input poses a serious potential for XSS, SQL injection, and command injection attacks. This is considered a bad coding practice so its usage should be audited and removed if present within your applications codebase.

Closing thoughts

React itself is not inherently insecure, While the community was quick to respond and patch the affected libraries the root vulnerability arises from unsafe handling of user-controlled input. Library usage is not a replacement for good coding practices.

Key takeaways

  • Don’t trust user input
  • Leverage React’s built-in protection
  • Validate and sanitise user input
  • Use established libraries to assists you
  • Stay vigilant; keep software updated, enable monitoring, logging and alerts in systems
  • Stay up to date on major cyber security incidents

Unsure whether your applications are affected by React2Shell? Our security specialists can help review your environment and recommend practical remediation steps. Get in touch.

References