cscli appsec-rules install crowdsecurity/vpatch-CVE-2026-109618This rule provides tentative virtual patching for CVE-2026-109618 (GHSA-w8hw-w9fx-j79w), a pre-authentication Remote Code Execution in PHP core: an out-of-memory error raised while PHP parses request input leaves request memory in an invalid state that the request shutdown then consumes. With Apache mod_php this happens before any application code runs.
Detection: The published exploit sends many empty file controls with deeply nested names: empty file controls do not count towards max_file_uploads, and PHP builds the whole name hierarchy six times for each of them. The rule blocks:
Both thresholds are conservative heuristics rather than measured bounds. Legitimate applications nesting form fields 12 levels deep (for instance deeply nested Drupal paragraphs) or uploading more than 50 files in one request will be blocked.
The file part count is written in SecLang because empty file controls are parsed as plain fields and can only be counted from the multipart part headers, which the rule DSL does not expose. Its alerts are reported as native_rule:2026109617 rather than under this rule's name.
Chunked multipart bodies are not blocked as such, since legitimate streaming clients send them too. They let a body bypass PHP's post_max_size check, but keep the AppSec body size limit action to drop (the default) rather than partial or allow, and keep a sane client_max_body_size on the reverse proxy.
Exploitation of the related CVE-2026-109619 through session upload progress is covered by crowdsecurity/vpatch-CVE-2026-109619.
Virtual patching mitigates exploitation attempts, but it does not fix the underlying vulnerability: upgrading PHP to a patched version is always recommended. If you cannot update, the advisory recommends enforcing memory_limit=-1, keeping post_max_size conservative and reducing max_input_nesting_level.
1name: crowdsecurity/vpatch-CVE-2026-1096182description: 'Tentative vpatch for CVE-2026-109618 : block requests crafted to exhaust PHP memory during input parsing.'3rules:4 # Deeply nested multipart names multiply the arrays PHP builds (six per empty file control).5 # Empty file controls are parsed as plain fields, hence BODY_ARGS_NAMES.6 - and:7 - zones:8 - HEADERS9 variables:10 - Content-Type11 transform:12 - lowercase13 match:14 type: contains15 value: 'multipart/'16 - zones:17 - BODY_ARGS_NAMES18 - FILES_NAMES19 match:20 type: regex21 value: '(?:\[[^\]]*\]){12}'22# Native rules: empty file controls are parsed as plain fields, so they can only be23# counted from the multipart part headers, which the DSL does not expose.24seclang_rules:25 - SecRule MULTIPART_PART_HEADERS "@rx (?i)^content-disposition:.*;\s*filename\*?\s*=" "id:2026109616,phase:2,pass,nolog,setvar:tx.cve_2026_109618_files=+1"26 - SecRule TX:cve_2026_109618_files "@gt 50" "id:2026109617,phase:2,deny,log,msg:'PHP - RCE (CVE-2026-109618) - too many multipart file parts',tag:'crowdsec-crowdsecurity/vpatch-CVE-2026-109618'"2728labels:29 type: exploit30 service: http31 confidence: 332 spoofable: 033 behavior: 'http:exploit'34 label: 'PHP - RCE'35 classification:36 - cve.CVE-2026-10961837 - attack.T119038 - cwe.CWE-90839