Creuto is now an OpenAI Select Partner Read More
The php2shell indicators of compromise vendors publish disagree: Sophos says hunt multipart POSTs, but Datadog's own reproduction used form-urlencoded.

Sophos tells you to hunt multipart POSTs. Datadog reproduced the bug with an application/x-www-form-urlencoded request. Both advisories are dated 21 October 2026, both are credible, and a detection built on the first one may not see the exploit described in the second. If you are assembling php2shell indicators of compromise this week, that conflict is the first thing to resolve, because one of the two commonly recommended mitigations follows from it and does not hold.
Here is what each source actually says, where they agree, and what a detection that covers both looks like.
Sophos's advisory tells defenders to review "multipart/form-data POSTs to endpoints that do not normally accept uploads, and requests containing the PHP_SESSION_UPLOAD_PROGRESS field". Its mitigation list includes "reject multipart/form-data requests at the web server or WAF". That is coherent guidance for an attack delivered through the upload-progress mechanism.
Datadog Security Labs reproduced CVE-2026-109618 on PHP 8.5.11 with Apache prefork and mod_php, on Debian 12 ARM64, with memory_limit=16M and post_max_size=64M. Their request used application/x-www-form-urlencoded, with "A single field name of about 3.5 MB" and binary data containing null bytes in an empty-name field. Datadog never names PHP_SESSION_UPLOAD_PROGRESS.
So the two describe different delivery paths. The most likely explanation is that these are two CVEs with two mechanisms — Sophos's guidance fits the upload-progress path, Datadog demonstrated a memory-exhaustion path on the other — and each vendor documented what it had in front of it. We cannot resolve it definitively, because neither advisory maps its guidance to a specific CVE in terms the other would recognise.
The practical consequence does not need resolving, though. A WAF rule that drops multipart requests does not touch a form-urlencoded request with a 3.5 MB field name. If that rule is your interim control while you patch, your interim control has a hole in it, and the hole is the shape Datadog actually demonstrated.
Datadog's are the most specific published, because they come from a reproduction rather than from reasoning. The PHP error log line, verbatim:
PHP Fatal error: Allowed memory size of 16777216 bytes exhausted (tried to allocate 3500032 bytes) in Unknown on line 0
And the corresponding Apache entry:
AH00052: child pid ... exit signal Segmentation fault (11)
Two cautions before you turn those into alerts. The byte figures are specific to Datadog's lab — 16777216 is their 16 MB memory_limit, so yours will differ and the number is not the signature. The pattern is "memory exhausted" plus "in Unknown on line 0", which indicates the failure happened before any application file was in scope. That is the genuinely unusual part, and it is worth a rule of its own.
Datadog is also explicit that you should not narrow too far: "Don't make your detection depend on ... a specific HTTP status, or a worker crash." For CVE-2026-109619 it lists softer signals — early configuration warnings, shutdown diagnostics, fatal errors and timeouts — with the right caveat: "No single signal is conclusive on its own, so correlate them."
Translated into something you can run today across the usual log locations:
# The memory-exhaustion pattern, independent of your memory_limit value
grep -rhE 'Allowed memory size of [0-9]+ bytes exhausted.*in Unknown on line 0' \
/var/log/php*.log /var/log/php-fpm/*.log 2>/dev/null
# Worker deaths around the same timestamps
grep -rhE 'AH00052|exit signal Segmentation fault|child exited' \
/var/log/apache2/error.log* /var/log/httpd/error_log* 2>/dev/null
# Web-stack processes that became a parent to a shell
ps -eo ppid,pid,comm,args | awk '$3 ~ /^(sh|bash|dash|python3?|perl|curl|wget)$/'
Run the first two together and compare timestamps, since Datadog's point about correlation is the operative one — a memory-exhaustion error alone is a tuning problem, and one arriving in the same second as a worker segfault on a non-upload endpoint is not. The ps check is a point-in-time snapshot, so it only catches a live implant; for anything historical you need process-creation telemetry from EDR or auditd, which is the gap most estates discover at this exact moment.
Combining the two gives a layered set rather than one rule. In rough order of signal quality:
| Layer | What to look for | Source |
|---|---|---|
| PHP error log | Memory exhaustion with "in Unknown on line 0"; fatal errors; timeouts | Datadog |
| Web server log | Worker segfaults, OOM-killer activity, unexpected child exits | Both |
| Request log | Multipart POSTs to non-upload endpoints; PHP_SESSION_UPLOAD_PROGRESS; abnormally large single field names | Sophos + Datadog |
| Process tree | php-fpm, php-cgi, httpd or apache2 spawning a shell or interpreter | Both |
| Filesystem | New or modified PHP files in web roots | Sophos |
| Network | Outbound connections from PHP workers; new cron jobs and SSH keys | Sophos |
| Identity | Successful administrative logins since 1 August 2026 | Sophos |
The process-tree row is the one that survives both accounts and any future variation in delivery, because it detects the outcome rather than the delivery. A web-stack process should never be the parent of a shell. Datadog points at its own rules for this shape, potential_web_shell_v2 and potential_web_shell_parent_v2, and the equivalent exists in most EDR products under some name — if you only have budget for one new rule this week, that is the one.
Sophos's 1 August date is not arbitrary and deserves attention: "The PHP Project received the first reports of these issues on August 11, 2026." Reviewing administrative logins from the start of August rather than from disclosure is the conservative reading of how long the window may have been open.
Worth being precise, because the gap between "scanning" and "compromise" is where most of the panic lives.
Amazon Threat Intelligence observed an exploitation attempt on 17 October 2026 through its MadPot honeypot network — four days before public disclosure. Tenable reports further attempts on 21 October that "suggest multiple actors", quotes Cloudflare's CTO saying "We are seeing early attacks emerging", and notes watchTowr "observing exploitation attempts against both". Datadog reports "broad untargeted scanning".
Against that: CISA's own alert on 21 October said it had not observed exploitation at the time of publication, and as of 22 October neither CVE was in the Known Exploited Vulnerabilities catalogue. Tenable also notes that pre-release CVE records carried "an incorrect CVSS score of 10.0" against PHP's own CVSS v4.0 rating of 9.2, and that while exploit code is circulating, "we have not verified that any of it works".
Read together: confirmed attempts, broad scanning, no public confirmation of successful compromise at scale. That justifies hunting now and does not justify assuming breach without evidence.
Two structural blind spots make absence of evidence weak here. Sophos names the first: "Many CDN and access logs do not record request bodies", so the 3.5 MB field name that is the clearest signal may never have been written down anywhere you can search. And the attack runs before application code, so your framework's logging, audit trail and application-level monitoring were never in the path.
That means the honest output of a hunt on most estates is "no evidence found, with known gaps in coverage" — not "not compromised". Write it that way. A clean hunt against logs that could not have captured the indicator is not a clean bill of health, and the difference matters if you later have to reconstruct a timeline.
The durable fix is the boring one: capture enough request metadata to answer this class of question. Not full bodies — field-name lengths, content types and response codes on endpoints that do not expect uploads would have been sufficient here, and that is a logging decision, not a security product. It is the same argument as auditing what your build actually ships rather than what you believe it ships.
Patch first — to 8.5.12, 8.4.27, 8.3.36 or 8.2.35 — because none of the above is a substitute, and on 8.1 or older there is no package to install at all. Then widen any interim WAF rule beyond multipart. Then run the process-tree and web-root checks, which are cheap and cover the outcome. Then review administrative logins back to 1 August. Then write down what your logs could not have told you.
If that last step keeps being the finding — and across a fortnight that also produced node2shell and five nginx CVEs it usually is — the gap is observability rather than detection content. Deciding what a pipeline must record to answer a question you have not been asked yet is part of how we approach QA and automation, because the alternative is discovering the gap during the incident.
Correlate several layers rather than relying on one rule: PHP memory-exhaustion errors reporting "in Unknown on line 0", web server worker segfaults, abnormally large single field names in request logs, and web-stack processes spawning shells. The process-tree check is the most reliable because it detects the outcome.
Datadog's reproduction used application/x-www-form-urlencoded with a single field name of about 3.5 MB. Sophos separately advises hunting multipart/form-data POSTs and the PHP_SESSION_UPLOAD_PROGRESS field. Cover both, because a rule limited to multipart misses the form-urlencoded shape Datadog demonstrated.
Not on its own. Sophos lists rejecting multipart/form-data at the web server or WAF as an interim measure, but Datadog reproduced the memory-exhaustion path using a form-urlencoded request, which such a rule would pass. Both vendors state that only patching actually fixes the vulnerabilities.
No. Sophos notes that many CDN and access logs do not record request bodies, and the exploit runs before application code, so your framework's audit trail was never in the path. Report findings as "no evidence found, with known coverage gaps" rather than as confirmation.
Attempts are confirmed. Amazon Threat Intelligence observed one on 17 October 2026, before disclosure, and Datadog reports broad untargeted scanning. CISA said it had not observed exploitation as of its 21 October alert, and neither CVE was in the Known Exploited Vulnerabilities catalogue on 22 October.
Sophos suggests reviewing successful administrative logins since 1 August 2026, because the PHP project received the first reports of these issues on 11 August 2026. Reviewing from the start of August rather than from public disclosure is the conservative reading of the exposure window.
Ready to take the first step towards unlocking opportunities, realizing goals, and embracing innovation? We're here and eager to connect.