Finder: https://react2shell.com/
PoC: https://github.com/lachlan2k/React2Shell-CVE-2025-55182-original-poc
Affected versions:
React 使用了 Node.js 等 JavaScript 运行时来负责提供 RSC 的渲染,运行时提供了 JavaScript 与浏览器之外的系统交互的能力,这使得漏洞能够上升到 RCE。
Next.js 框架在默认情况下启用了 RSC 且对用户输入验证不足,这使得此次漏洞影响广泛且利用十分简单。
https://zh-hans.react.dev/reference/rsc/server-components

我们从修复 commit 入手,就可以快速定位到漏洞点。
https://github.com/facebook/react/pull/35277/commits/e2fd5dc6ad973dd3f220056404d0ae0a8707998d
修复前:https://github.com/facebook/react/tree/36df5e8b42a97df4092f9584e4695bf4537853d5
通过阅读 react-server#flight-rendering 可以知道 RSC 的实现分为 Flight 和 Fizz 两部分,而不安全的序列化是由 Flight 约定并实现的。你可以通过 https://rscexplorer.dev/ 了解渲染过程。
容易分析出 RCE 的漏洞极易出现在 Flight 的序列化反序列化过程,我们开始跟踪。
Flight 实现了一套自己的序列化协议,它允许如下类型被序列化 packages/react-server/src/ReactFlightServer.js#L3469-L3494
// <https://github1s.com/facebook/react/blob/36df5e8b42a97df4092f9584e4695bf4537853d5/packages/react-server/src/ReactFlightServer.js#L489-L523>
// Serializable values
export type ReactClientValue =
// Server Elements and Lazy Components are unwrapped on the Server
| React$Element<component(...props: any)>
| LazyComponent<ReactClientValue, any>
// References are passed by their value
| ClientReference<any>
| ServerReference<any>
// The rest are passed as is. Sub-types can be passed in but lose their
// subtype, so the receiver can only accept once of these.
| React$Element<string>
| React$Element<ClientReference<any> & any>
| ReactComponentInfo
| string
| boolean
| number
| symbol
| null
| void
| bigint
| ReadableStream
| $AsyncIterable<ReactClientValue, ReactClientValue, void>
| $AsyncIterator<ReactClientValue, ReactClientValue, void>
| Iterable<ReactClientValue>
| Iterator<ReactClientValue>
| Array<ReactClientValue>
| Map<ReactClientValue, ReactClientValue>
| Set<ReactClientValue>
| FormData
| $ArrayBufferView
| ArrayBuffer
| Date
| ReactClientObject
| Promise<ReactClientValue>; // Thenable<ReactClientValue>
此次漏洞的入口点在 packages/react-server/src/ReactFlightActionServer.js,这是一个处理 Server Action 的服务端,生产中的作用是可以让用户提交表单后,接收序列化的表单数据,并将其反序列化。服务端维护了类型为 Response 的上下文,