The React2Shell Story
A security researcher's accidental deep dive into React's undocumented "Flight" protocol uncovered a critical remote code execution vulnerability, React2Shell. This meticulous journey, sparked by a hacker's curiosity, details the intricate steps from understanding a proprietary protocol to weaponizing its leniencies for full RCE. It's a masterclass in vulnerability research, showcasing how complex systems can harbor "glaring omissions of safety checks" with severe consequences.
The Lowdown
“React2Shell” is the story of a security researcher's unexpected discovery of a critical Remote Code Execution (RCE) vulnerability within Meta's React framework, specifically its "Flight" protocol. What began as an effort to understand a proprietary communication mechanism for modern web applications quickly escalated into a full-blown vulnerability research project, culminating in a high-severity RCE that affected millions of websites.
- Undocumented Protocol Discovery: The author, a professional hacker, set out to understand "Flight," a custom protocol used by React Server Components (RSC) and React Server Functions in frameworks like Next.js for client-server communication of complex JavaScript objects. Despite its critical role, Flight lacked formal documentation or specifications, making reverse-engineering essential.
- Initial Anomaly - Prototype Property Access: Early investigations revealed that Flight allowed referencing inherited prototype properties (e.g.,
Number.prototype.toString) on objects, an unusual leniency described by Next.js creator Guillermo Rauch as a "glaring omission of a safety check." - Weaponization Hypothesis: The initial goal was to abuse Flight's ability to transmit complex objects to exploit common developer input validation mistakes in Next.js applications, where TypeScript's build-time type annotations could create a false sense of runtime security.
- Breakthrough - Abusing Thenables: A pivotal discovery was
await decodeReply(...)'s lenient handling of "thenables" (objects with a.thenmethod). By crafting a malicious thenable, the attacker could force React to call arbitrary functions, enabling controlled execution paths within React's internal processes. - Accessing Internal
ChunkObjects: Further investigation revealed that Flight's internalChunkobjects, used for managing asynchronous data, inherited fromPromise. This allowed the researcher to manipulateChunk.prototype.thenagainst attacker-controlled objects, effectively spoofing internal React state. - The RCE Chain: The final exploit involved a complex chain of manipulations. Rather than spoofing server manifests directly, the researcher identified specific points in
Chunkcode where React called functions with controllable arguments (e.g.,_formData.get(...)during file blob processing). This allowed constructing and executing arbitrary JavaScript code by ultimately callingModule._loadin Node.js environments. - Responsible Disclosure: The vulnerability was reported to Meta, who swiftly triaged, confirmed, and worked with the React and Vercel teams to develop and deploy a fix (CVE-2025-55182) within days, coordinating with industry partners before public disclosure.
Conclusion: The React2Shell story is a compelling account of how persistence, deep technical understanding, and a willingness to explore undocumented corners of a widely used framework can uncover critical vulnerabilities. It serves as a stark reminder that even highly battle-tested systems can have subtle, yet devastating, security flaws.