CVE-2026-105857 CrowdStrike LogScale · LogScale

Detect Payload CMS Form Builder Plugin Remote Code Execution (CVE-2026-105857) in CrowdStrike LogScale

Detects exploitation of CVE-2026-105857, a CVSS 10.0 remote code execution vulnerability in the @payloadcms/plugin-form-builder npm package (CWE-94 Code Injection / CWE-1321 Prototype Pollution). Affected versions are < 3.90.0 and the 4.0.0 canary line >= 4.0.0-canary.0 and < 4.0.0-canary.34. The form-builder plugin evaluates attacker-influenced input when processing dynamic form submissions and conditional/calculated field logic, allowing an unauthenticated attacker to inject and execute arbitrary code or pollute the Object prototype to achieve RCE on the Node.js server hosting the Payload CMS application. A public PoC is available via GHSA-r488-j9vj-wx3q. These detections surface the HTTP exploitation attempts against form submission endpoints, prototype-pollution payload markers (__proto__, constructor, prototype), and post-exploitation child-process / reverse-shell behavior spawned from the Node.js process.

MITRE ATT&CK

Tactic
Initial Access Execution

LogScale Detection Query

CrowdStrike LogScale (LogScale)
cql
#event_simpleName=ProcessRollup2 ParentBaseFileName=/^(node|npm|next-server)$/i
| ImageFileName=/\/(sh|bash|dash|python3?|perl|curl|wget|nc|ncat)$/i
| groupBy([ComputerName, ParentBaseFileName, ImageFileName, CommandLine], function=count(as=spawnCount))
| spawnCount >= 1
critical severity medium confidence

CrowdStrike CQL (LogScale) detection for suspicious shell / network-tool child processes spawned by a Node.js (Payload CMS) parent, indicating post-exploitation of CVE-2026-105857.

Data Sources

CrowdStrike Falcon EDR

Required Tables

ProcessRollup2

False Positives & Tuning

  • Node.js applications legitimately spawning shells for build or deploy tasks.
  • SSR frameworks invoking helper binaries (image/PDF generation).
  • DevOps tooling running npm lifecycle scripts that shell out.

Other platforms for CVE-2026-105857


Testing Methodology

Validate this detection against 3 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.

  1. Test 1Prototype-pollution payload to Payload form-submission endpoint

    Expected signal: Web/proxy access log entry: POST /api/form-submissions with request body containing __proto__.

  2. Test 2Code-injection expression in form conditional logic

    Expected signal: Web access log entry: POST /api/forms with body containing constructor.constructor and child_process markers.

  3. Test 3Simulated post-exploitation shell spawned by Node.js

    Expected signal: Process-creation event: parent process 'node' spawning '/bin/sh' executing 'id'.


Response Playbook

Triage

  1. Confirm whether the targeted host runs a Payload CMS application using @payloadcms/plugin-form-builder and check the installed version against the affected ranges (< 3.90.0, or >= 4.0.0-canary.0 and < 4.0.0-canary.34) via `npm ls @payloadcms/plugin-form-builder` or the lockfile.
  2. Pull the full request body for the flagged form-submission request(s) and inspect for prototype-pollution keys (__proto__, constructor.prototype) or injected code expressions in field definitions / conditional logic.
  3. Correlate the source IP against authentication logs and WAF/proxy logs to determine whether the request was unauthenticated and whether it belongs to a known scanner or a novel actor.
  4. Review the Node.js process tree on the host for any child processes (sh, bash, python, curl, nc) spawned within minutes of the suspicious request.

Containment

  1. Block the offending source IP(s) at the WAF/edge and rate-limit or temporarily disable the public form-submission endpoints until patched.
  2. Upgrade @payloadcms/plugin-form-builder to >= 3.90.0 (or the 4.0.0 line to >= 4.0.0-canary.34) and redeploy; restart the Node.js service to clear any polluted in-memory prototype state.
  3. If post-exploitation child processes are confirmed, isolate the host from the network and preserve it for forensics.

Evidence Collection

  1. Capture the raw HTTP request(s) (headers + body) to the form endpoints, the web/proxy access logs, and the application logs covering the exploitation window.
  2. Collect the Node.js process memory/metadata, the process-creation telemetry (EDR), and any files written to the webroot, /tmp or the application working directory after the request.
  3. Preserve the installed package tree and lockfile to document the vulnerable version in place at time of compromise.

Escalation Criteria

  • !Escalate to incident response immediately if a child process (shell, interpreter, or network tool) was spawned by the node process following the request, indicating confirmed RCE.
  • !Escalate if outbound connections, new persistence, credential access, or lateral movement are observed from the host after the suspicious request.
  • !Escalate if the vulnerable version is confirmed and the endpoint is internet-exposed, regardless of whether code execution is yet proven.

Investigation Guide

Related Techniques

Forensic Artifacts

  • >Web/proxy access logs showing POST/PUT/PATCH requests to /api/forms or /form-submissions with __proto__/constructor/prototype tokens.
  • >Node.js application logs and process-creation (EDR) records showing child shell/interpreter processes.
  • >Files newly written to the application working directory, webroot, or /tmp after the request; the installed package lockfile documenting the vulnerable version.

Tuning Guidance

Baseline the legitimate field names and payload shapes of your form submissions first; many false positives come from free-text fields that legitimately contain the words 'constructor' or 'prototype'. Tighten the marker match to JSON key positions (e.g. '"__proto__":' or 'constructor":{"prototype"') rather than substring presence, and scope the detection to the specific host(s) running the Payload CMS application. Pair the HTTP-layer detection with the EDR child-process detection to raise confidence to high only when both fire within a short window.


Hunting Queries

Hunt across historical web logs for prototype-pollution / code-injection payloads sent to Payload CMS form-builder endpoints.

Hunting — KQL
kql
W3CIISLog | where csMethod in~ ("POST","PUT","PATCH") | where tolower(csUriStem) has_any ("form-submissions","/api/forms") | where tolower(csUriQuery) has_any ("__proto__","constructor","prototype") | project TimeGenerated, cIP, csUriStem, csUriQuery
Hunting — SPL
spl
index=web (uri_path="*/form-submissions*" OR uri_path="*/api/forms*") (method=POST OR method=PUT OR method=PATCH) | search _raw="*__proto__*" OR _raw="*constructor*" OR _raw="*prototype*" | table _time src_ip uri_path method

Atomic Red Team Tests

Test 1 Prototype-pollution payload to Payload form-submission endpoint
linux

Sends a crafted JSON form submission containing a __proto__ prototype-pollution key to the form-builder submission endpoint in a lab instance to generate HTTP-layer detection telemetry.

Command

bash
curl -s -X POST http://127.0.0.1:3000/api/form-submissions -H 'Content-Type: application/json' -d '{"form":"contact","submissionData":[{"field":"name","value":"x"}],"__proto__":{"polluted":"cve-2026-105857"}}'

Cleanup

bash
echo 'No cleanup required; restart the Node.js service to clear in-memory prototype state: pm2 restart payload || true'

Expected Telemetry

Web/proxy access log entry: POST /api/form-submissions with request body containing __proto__.

Expected Detection

The kql/spl/qradar_aql/sumo_logic/chronicle_yaral HTTP detections fire on the __proto__ marker in the form-submission request.

Test 2 Code-injection expression in form conditional logic
linux

Submits a form payload with a code-expression injected into a calculated/conditional field to simulate the CWE-94 code-injection path of CVE-2026-105857.

Command

bash
curl -s -X POST http://127.0.0.1:3000/api/forms -H 'Content-Type: application/json' -d '{"title":"t","fields":[{"blockType":"text","name":"a","defaultValue":"{{constructor.constructor(\"return process\")().mainModule.require(\"child_process\").execSync(\"id\")}}"}]}'

Cleanup

bash
echo 'Remove any test form created: use the admin UI or DB to delete the form titled t'

Expected Telemetry

Web access log entry: POST /api/forms with body containing constructor.constructor and child_process markers.

Expected Detection

HTTP detections fire on constructor/prototype markers; if execution occurs, EDR detections fire on the node-spawned child process.

Test 3 Simulated post-exploitation shell spawned by Node.js
linux

Spawns a child shell from a node parent process to emulate successful RCE post-exploitation and exercise the Elastic EQL and CrowdStrike CQL process-based detections.

Command

bash
node -e "require('child_process').execSync('/bin/sh -c id', {stdio:'inherit'})"

Cleanup

bash
echo 'No persistent artifacts created by this test.'

Expected Telemetry

Process-creation event: parent process 'node' spawning '/bin/sh' executing 'id'.

Expected Detection

The elastic_eql and crowdstrike_cql detections fire on the node-parented shell child process.

Related Detections