Skip to content

CVE-2025-71389 — Cal.com Unauthenticated RCE via Next.js RSC Deserialization

Key facts

CVE-2025-71389 is a Critical (10.0) vulnerability: Cal.com Unauthenticated RCE via Next.js RSC Deserialization. This entry ships ready-to-deploy detection and prevention rules (Snort, YARA, Nginx, Apache) plus a detection-only PoC and a Docker test lab.

CVE CVE-2025-71389
Severity Critical (10.0)
Detection / prevention Snort, YARA, Nginx, Apache
PoC poc.py
Source 2026/CVE-2025-71389/

Details

CVE-2025-71389 is a Critical (10.0) vulnerability: Cal.com Unauthenticated RCE via Next.js RSC Deserialization. This entry ships a detection-only proof-of-concept (PoC), a Docker test lab, and ready-to-deploy detection and prevention rules (Snort, YARA, Nginx, Apache) — see Detection and prevention below. Source: NVD record.

CVSS v3 10.0 (Critical)
CWE CWE-94 Code Injection (insecure deserialization)
Affected Cal.com (calcom/cal.diy) < 5.9.9
Fixed 5.9.9
Upstream Next.js CVE-2025-55182
Vector Network / Unauthenticated

For authorized security testing, CTF, and research only.

Summary

Cal.com bundles a version of Next.js whose React Server Components (RSC) request handling deserializes attacker-controlled input. A remote, unauthenticated attacker can send a crafted RSC request (a "server action" payload) that causes arbitrary code to run during server-side processing — no auth, no user interaction. It derives from upstream Next.js CVE-2025-55182 and is fixed in Cal.com 5.9.9 by updating the dependency.

Root cause

The server treats the serialized RSC action payload as trusted and materializes/executes it without verifying it corresponds to a registered server action. The fix pins a Next.js version that validates the action reference before dispatch.

Detection (poc.py)

Non-destructive: sends an RSC-style request (Next-Action header) whose serialized action encodes a benign arithmetic marker. If the server evaluates it (marker appears in the response), untrusted action payloads are being deserialized/executed → VULNERABLE. No OS/process payloads are sent.

python poc.py --target http://TARGET:5003

Lab

docker compose up --build      # vulnerable on :5003, patched on :5004
./run-tests.sh

Remediation

  • Upgrade Cal.com to 5.9.9+ (pulls the patched Next.js).
  • Only dispatch RSC server actions from a validated registry; never execute action payloads by reference from the request.
  • Apply prevention/ to block unregistered Next-Action payloads at the edge.

Detection and prevention

Ready-to-deploy defensive rules for CVE-2025-71389, for authorized testing and blue-team detection engineering:

References: NVD — CVE-2025-71389 · full write-up on the searchable site

Detection & prevention rules

# CVE-2025-71389 — Cal.com Next.js RSC deserialization RCE (Snort/Suricata)

alert http $EXTERNAL_NET any -> $HOME_NET any ( \
    msg:"CVE-2025-71389 Cal.com RSC server-action inline eval payload"; \
    flow:established,to_server; http.method; content:"POST"; \
    http.header; content:"Next-Action"; nocase; \
    http.request_body; pcre:"/\"type\"\s*:\s*\"eval\"|__proto__|constructor\s*\(/i"; \
    classtype:web-application-attack; sid:2025071389; rev:1; )

:material-file-download: prevention/snort.rules

/*
 * CVE-2025-71389 — Cal.com / Next.js RSC deserialization RCE
 * Detect captured RSC server-action exploit payloads.
 */

rule CVE_2025_71389_rsc_action_exploit
{
    meta:
        cve = "CVE-2025-71389"
        description = "Next.js RSC server-action inline-eval / prototype-pollution payload"
        severity = "critical"
    strings:
        $h = "Next-Action" ascii
        $rsc = "text/x-component" ascii
        $e1 = "\"type\":\"eval\"" ascii nocase
        $e2 = "__proto__" ascii
        $e3 = "child_process" ascii
    condition:
        ($h or $rsc) and any of ($e1, $e2, $e3)
}

:material-file-download: prevention/yara.yar

# CVE-2025-71389 — Cal.com Next.js RSC deserialization RCE
# Block RSC/server-action requests carrying inline executable payloads.

location / {
    # RSC action requests that embed an eval/type payload are never legitimate.
    if ($request_body ~* "\"type\"\s*:\s*\"eval\"") { return 403; }
    if ($http_next_action != "") {
        # Optionally restrict action dispatch to same-origin/authenticated flows.
        # e.g. require a valid session cookie before allowing server actions.
    }
    proxy_pass http://127.0.0.1:5003;
    proxy_set_header Host $host;
    client_body_in_single_buffer on;
}

:material-file-download: prevention/nginx.conf

# CVE-2025-71389 — Cal.com Next.js RSC deserialization RCE (Apache + ModSecurity)

# Block RSC server-action requests that carry inline executable/eval payloads.
SecRule REQUEST_HEADERS:Next-Action "@rx .+" \
    "id:2025071389,phase:2,deny,status:403,log,\
     msg:'CVE-2025-71389 Cal.com RSC action with inline payload',chain"
    SecRule REQUEST_BODY "@rx \"type\"\s*:\s*\"eval\"|__proto__|constructor\s*\(" "t:none"

:material-file-download: prevention/httpd.conf

Frequently asked questions

What is CVE-2025-71389?

CVE-2025-71389 is a Critical (10.0) vulnerability: Cal.com Unauthenticated RCE via Next.js RSC Deserialization. This entry ships ready-to-deploy detection and prevention rules (Snort, YARA, Nginx, Apache) plus a detection-only PoC and a Docker test lab.

How do I detect CVE-2025-71389?

Deploy the Snort and YARA detection rule included with this entry (see Detection & prevention rules below), then validate it against the detection-only PoC in the Docker test lab.

How do I block or mitigate CVE-2025-71389?

Apply the Nginx and Apache mitigation config included with this entry, and upgrade to a fixed version per the vendor advisory (see the NVD record for affected versions).


For authorized security testing and research only. See the full source and NVD record.