Attack scenariosPHP vulnerability
PHP2Shell, code execution before the application runs
Two critical flaws in PHP itself let an unauthenticated request run commands on the server while PHP is still parsing it. Application code, logins and access checks never get a chance to act.
The problem
PHP turns a form submission into $_POST and $_FILES before the script starts. Both flaws live in that stage, so every PHP script on the server exposes them, even one that only prints a page.
- CVE-2026-109618. A memory error interrupts PHP in the middle of building the request data. The cleanup that follows treats the half-built structures as valid, and an attacker who controls the leftover memory controls what the cleanup does.
- CVE-2026-109619. A PHP worker keeps state from an earlier request that points into freed memory. A later request from the attacker reads that stale state. Upload processing with session upload progress, which PHP enables by default, is one confirmed way in.
Both are rated 9.2 in CVSS v4. Exploitation attempts were reported four days before the public disclosure on 21 October 2026, and CISA asks organizations to patch immediately. PHP 8.1 and older are past end of life and depend on vendor backports. The PHP configuration changes published as temporary mitigations reduce the exposure but do not close it.
Why there is no attack request here
The flaws are new and many servers are not patched yet, so this page does not publish a working request. The detection is described by what the request looks like to Filter, not by how to build one.
What Mikiri WAF blocks, in both plans
Filter parses the request body itself and checks it before anything is forwarded to PHP. Two independent layers stop PHP2Shell requests, and both block on their own, without the machine-learning step.
Limits of the form body
CVE-2026-109618 needs a form body that makes PHP allocate far more memory than a real form does. Filter measures the structure of the body while it parses it and blocks a body that goes over a limit as a violation of the request structure. The limits are on by default, apply to every host and are changed in WMC or through the API.
- Multipart forms (
waf_multipart_limits): the number of parts, the header lines and header bytes of one part, and the nesting depth of a field name. - URL-encoded forms (
waf_urlencoded_limits): the number of parameters, the length of one parameter name and its nesting depth. Filter counts an encoded bracket as a bracket, because PHP decodes the name before it reads the nesting. - Control characters in a URL-encoded body. Null bytes and other control characters, raw or encoded as
%00, have no place in a form submission. Filter normally removes them before signatures run, so a signature cannot see them. The URL-encoded limits are checked on the body exactly as it was sent, before decoding, so these characters are caught there.
The defaults are well above what ordinary forms send. An application that really submits larger forms gets a higher limit, or 0 to turn one limit off, without switching off the rest of the protection.
Signatures
These rules arrive with signature updates and also hold when a limit has been raised or turned off:
- The upload progress field in a form. A
multipart/form-datapart named for PHP session upload progress, the entry point of the upload case of CVE-2026-109619. - Deeply nested field names. A form field name nested sixteen levels or more, as in
a[1][2]…. Each level makes PHP allocate another array while it builds the request data, which is the kind of pressure CVE-2026-109618 relies on. - Oversized parameter names. A URL-encoded parameter whose name runs to thousands of characters, a size that real forms never use.
- A malformed form content type. A
Content-Typein whichmultipart/form-datais followed by anything other than the usual parameter separator. PHP and an inspecting proxy can read such a header differently, so Filter refuses it instead of guessing which boundary PHP would use.
The request is blocked by Filter and never reaches PHP, so the protection works in front of an unpatched or end-of-life PHP version. It does not replace the update: the advisory expects other code paths with the same flaw, and the only complete fix is a fixed PHP release.
What Enterprise adds: finding the exposed servers
Blocking buys time; the servers still have to be updated. The scanner built into Enterprise includes the VOC module, named after the OWASP category Vulnerable and Outdated Components. It reads the PHP version that a target already reveals in its X-Powered-By or Server header, on the root page and on a few crawled pages, and reports a release below PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35, and every PHP 8.1 or older, as affected by PHP2Shell.
The module sends no attack payload and contacts only the target. Each finding is shown in WMC with the header it came from and a curl command to read the header again. A distribution that backports the fix keeps the old version string, so confirm the installed build before acting on a finding. A server that hides its version is not reported, and needs your own inventory. The modules are listed in the scanner documentation.
What Enterprise adds: blocking the response
Request rules stop the attack on its way in. Enterprise also inspects what the application sends back, and blocks the response before it leaves the perimeter. This covers two situations that a request rule cannot.
Memory disclosure during the attack. A reliable exploit needs addresses from the PHP process, and one public technique reads them from a session cookie that PHP fills with leaked memory. Filter blocks a response whose PHPSESSID cookie contains characters that a real session ID never has, or is longer than a session ID can be. The attacker does not receive the addresses, and the response is recorded as an attack.
An application that is already compromised. The server may have been exploited before PHP was updated, before Mikiri WAF was deployed, or through a path that no request rule describes. From that point the attacker works through HTTP responses: the output of a command, the contents of a system file, the page of an uploaded web shell. Response analysis blocks these responses:
- the output of Unix commands and shell utilities;
- the contents of
/etc/passwdand/etc/shadow, private keys and certificates; - the pages of known PHP and ASP web shells;
- PHP source code and PHP variables that should never reach a visitor.
The attacker no longer sees the result of what was run, a web shell stops being usable from the browser, and data does not leave through the application. Each blocked response is recorded in WMC, which turns a quiet compromise into an event to investigate.
Response blocking does not undo a command that already ran, and it does not see a channel that bypasses the application, such as a reverse shell. Use it to contain the damage while you update PHP, rebuild the affected servers and look for unexpected processes started by the web server.
Response analysis is turned on for the URLs you choose, as described in Response analysis. The response rules come from the same signature service and update automatically.
What you see in WMC
A request blocked by a signature appears under the host in Attacks with the zone where the rule matched, the body or the Content-Type header, the rule and its description, and the mark that the request was blocked. A request over a body limit appears with blocking type 15, and its description names the limit, the value the request reached and the setting to change. A blocked response appears in the same list with blocking type 17.
Expected result, body limit
- Blocking type15, violation of the request structure
- DescriptionThe limit, the value reached and the setting, for example waf_urlencoded_limits
- BackendRequest not forwarded
Expected result, signature
- Response403 from Filter
- Zonebody or the content-type header
- BackendRequest not forwarded
Expected result, response (Enterprise)
- ResponseFilter block page instead of the application page
- Blocking type17, blocked response
- ZoneResponse body or the set-cookie header
Check it without an exploit
These checks use harmless requests against a test application behind Mikiri WAF.
- Body limits. Submit a URL-encoded form with the value
a=%00, or a field nested seventeen levels deep, as ina[x][x]…. Filter blocks the request with blocking type15. - Request rules. Submit a multipart form with a field named after the PHP upload progress setting,
PHP_SESSION_UPLOAD_PROGRESSby default. Filter blocks the request. An application that uses upload progress on purpose needs an exception for that path. - Exposed versions, Enterprise. Scan a test host whose
X-Powered-Byheader shows a PHP release below the fixed ones. The scan reports a VOC finding for PHP2Shell. - Response rules, Enterprise. Turn on response analysis for a test URL that prints the contents of
/etc/passwdor returns aPHPSESSIDcookie longer than 256 characters. Filter blocks the response.
To record a request or a response without blocking it, switch the host or the URL to detection mode first.
Check your PHP applications
Deploy Mikiri WAF on premises in front of your PHP applications and run these checks on your own traffic. Evaluation is free, and application traffic stays on premises.
