Critique

CVE-2026-109618 — PHP : exécution de code

  • Publié le
  • Mis à jour
  • Lecture13 min
  • CVECVE-2026-109618

CVE-2026-109618 permet une exécution de code à distance sans authentification sous le compte du processus web PHP. L'exploitation a été validée par HTTP contre Apache mod_php avec les limites PHP par défaut et plusieurs processus workers. La correction est urgente : le CERT-FR signale des preuves de concept pour certains déploiements PHP et recommande l'isolement des équipements affectés puis leur migration vers une version maintenue et corrigée. Cette information ne démontre pas une exploitation en conditions réelles. Les branches PHP 8.2, 8.3, 8.4 et 8.5 sont affectées avant, respectivement, 8.2.35, 8.3.36, 8.4.27 et 8.5.12.

Tri IA initial, TL;DR français sourcé et revue séparée ; champs absents : inconnu.

Composant : PHP

Versions : [{"lessThan": "8.2.35", "status": "affected", "version": "8.2.*", "versionType": "semver"}, {"lessThan": "8.3.36", "status": "affected", "version": "8.3.*", "versionType": "semver"}, {"lessThan": "8.4.27", "status": "affected", "version": "8.4.*", "versionType": "semver"}, {"lessThan": "8.5.12", "status": "affected", "version": "8.5.*", "versionType": "semver"}]

Priorité éditoriale : critique

CVE : CVE-2026-109618

Date source : 2026-10-21T13:34:25Z

Référence — titre original

RCE via OOM corruption

Citation originale (en, non traduite)

PHP uses `longjmp()` for out-of-memory (OOM) errors to exit the current context and abort handling of the request. In some contexts, request memory is temporarily reachable before it is fully initialized. If any allocation fails at that point, PHP does not properly account for the early exit and leaves the request memory in an invalid state. The failed allocation does not need to be related to the invalid memory. The request shutdown procedure may then read or branch on it. Multiple OOM strategies can consistently trigger this condition and lead to remote code execution (RCE).

Avis de l’éditeur : inconnu sauf référence explicitement acquise.

Source acquise

Priorité critique — analyse et éléments sourcés

Résumé opérationnel (TL;DR)

CVE-2026-109618 permet une exécution de code à distance sans authentification sous le compte du processus web PHP. L'exploitation a été validée par HTTP contre Apache mod_php avec les limites PHP par défaut et plusieurs processus workers.

The confirmed impact is unauthenticated remote code execution as the web worker account. Complete remote code execution was validated over HTTP against mod_php with default PHP input and memory limits and normal prefork configurations with multiple workers.

Source de cet élément

La correction est urgente : le CERT-FR signale des preuves de concept pour certains déploiements PHP et recommande l'isolement des équipements affectés puis leur migration vers une version maintenue et corrigée. Cette information ne démontre pas une exploitation en conditions réelles.

Le CERT-FR a connaissance de preuves de concept pour les vulnérabilités CVE-2026-109618 et CVE-2026-109619 pour des déploiements spécifique de PHP.

Source de cet élément

Les branches PHP 8.2, 8.3, 8.4 et 8.5 sont affectées avant, respectivement, 8.2.35, 8.3.36, 8.4.27 et 8.5.12.

{"affected_versions": [{"lessThan": "8.2.35", "status": "affected", "version": "8.2.*", "versionType": "semver"}, {"lessThan": "8.3.36", "status": "affected", "version": "8.3.*", "versionType": "semver"}, {"lessThan": "8.4.27", "status": "affected", "version": "8.4.*", "versionType": "semver"}, {"lessThan": "8.5.12", "status": "affected", "version": "8.5.*", "versionType": "semver"}]

Source de cet élément

Impact

Apache mod_php est exposé avant même l'exécution du code applicatif : l'analyse automatique du corps peut épuiser la mémoire au démarrage, puis la procédure de fermeture traite un état invalide.

Apache mod_php unconditionally invokes the request shutdown procedure, even when request startup has failed. During request startup, automatic body parsing can exhaust the configured memory limit and exit the request in a context where state is temporarily invalid. Shutdown then processes this invalid state. This happens entirely before any application-specific code begins execution.

Source de cet élément

FPM est considéré comme susceptible sur la base de l'analyse du code, mais aucun exploit complet n'y a été démontré. La sortie du processus enfant lors d'un échec de démarrage évite ce chemin précis ; une erreur mémoire après démarrage reste susceptible d'exposer un état invalide.

FPM exits the child when request startup fails. This prevents consumption of the invalid state and removes the child from the pool. After normal startup, OOM may still be reached in a context failing to account for an early exit, with the invalid state being processed during request shutdown. Source analysis therefore supports FPM as a susceptible, though no complete FPM exploit has been demonstrated for this SAPI.

Source de cet élément

FrankenPHP est probablement exposé à des attaques indépendantes de l'application ; pour LSAPI, les exploits dépendant de l'application sont jugés probables, mais non validés.

Source analysis indicates that FrankenPHP, analogous to Apache mod_php, calls the request shutdown procedure unconditionally, making it likely susceptible to application-independent attacks. LSAPI models FPM, with application-specific exploits being likely but unvalidated.

Source de cet élément

Mécanisme et prérequis

Lors d'un épuisement mémoire, longjmp() interrompt le traitement alors que certaines structures de requête peuvent être accessibles sans être complètement initialisées. La fermeture de la requête peut ensuite lire cet état invalide ou l'utiliser pour un branchement, jusqu'à permettre une exécution de code.

PHP uses `longjmp()` for out-of-memory (OOM) errors to exit the current context and abort handling of the request. In some contexts, request memory is temporarily reachable before it is fully initialized. If any allocation fails at that point, PHP does not properly account for the early exit and leaves the request memory in an invalid state. The failed allocation does not need to be related to the invalid memory. The request shutdown procedure may then read or branch on it. Multiple OOM strategies can consistently trigger this condition and lead to remote code execution (RCE).

Source de cet élément

Des requêtes multipart peuvent provoquer l'épuisement mémoire malgré les limites apparentes : absence de longueur déclarée exploitable, nombre non borné d'en-têtes par partie, ou champs de fichiers vides générant des métadonnées sans être comptés dans max_file_uploads. Les noms de champs imbriqués amplifient le travail.

Several multipart parsing problems can let a request reach OOM while remaining within its apparent PHP limits:

– A multipart request without a usable declared content length may pass the initial `post_max_size` check and continue supplying decoded body data.
– A multipart part can contain an unrestricted number of headers. Representing these headers inside PHP can use substantially more memory than their wire representation, allowing a request within `post_max_size` to exhaust the normal `memory_limit`.
– Empty file controls do not count towards `max_file_uploads` but still create the normal file metadata arrays. Nested field names multiply the generated array work.

Source de cet élément

Indicateurs publiés par l’éditeur

Non établi par les sources acquises.

Mesures documentées

Updating to a PHP release containing the patch to this vulnerability is the _only_ complete mitigation.

Updating to a PHP release containing the patch to this vulnerability is the _only_ complete mitigation.

Source de cet élément

Le CERT-FR recommande d'isoler les équipements affectés puis de procéder à la migration vers une version maintenue et avec les derniers correctifs de sécurité dès publication du correctif éditeur.

Le CERT-FR recommande d'isoler les équipements affectés puis de procéder à la migration vers une version maintenue et avec les derniers correctifs de sécurité dès publication du correctif éditeur.

Source de cet élément

For installations that cannot update, setting and enforcing `memory_limit=-1` administratively is the primary configuration mitigation. It removes the predictable per-request limit that enables the confirmed exploit with a controllable OOM. This is not a complete mitigation. If `mmap()` or another underlying allocation fails, PHP can still use `longjmp()` while incomplete request memory is reachable. Restart every PHP worker and confirm that no pool, directory or application setting restores a finite PHP memory limit.

For installations that cannot update, setting and enforcing `memory_limit=-1` administratively is the primary configuration mitigation. It removes the predictable per-request limit that enables the confirmed exploit with a controllable OOM. This is not a complete mitigation. If `mmap()` or another underlying allocation fails, PHP can still use `longjmp()` while incomplete request memory is reachable. Restart every PHP worker and confirm that no pool, directory or application setting restores a finite PHP memory limit.

Source de cet élément

Keep `post_max_size` conservative and independently enforce the decoded request size at the frontend. Reduce `max_input_nesting_level`, and bound the number of input variables, multipart parts, headers within each part and uploads. These controls reduce hard OOM and denial of service risk even after applying the patch, but do not replace updating. If the application does not use multipart form data, block such requests at the frontend before they reach PHP.

Keep `post_max_size` conservative and independently enforce the decoded request size at the frontend. Reduce `max_input_nesting_level`, and bound the number of input variables, multipart parts, headers within each part and uploads. These controls reduce hard OOM and denial of service risk even after applying the patch, but do not replace updating. If the application does not use multipart form data, block such requests at the frontend before they reach PHP.

Source de cet élément

Do _not_ use `RLIMIT_AS` or `RLIMIT_DATA`, as these will cause `mmap()` to fail once the memory limit is reached, triggering the vulnerable `longjmp()` path.

Do _not_ use `RLIMIT_AS` or `RLIMIT_DATA`, as these will cause `mmap()` to fail once the memory limit is reached, triggering the vulnerable `longjmp()` path.

Source de cet élément

Aucune annexe présentée comme intégrale : consulter l’avis officiel lié.

Attribution : avis officiel de l’éditeur, sans corroboration indépendante alléguée. La date d’ajout au catalogue KEV n’est pas une date de divulgation. Les échéances CISA affichées ne constituent pas des obligations universelles.

Correctifs et versions — texte original de l’éditeur, non traduit

The patch removes `longjmp()` for OOM, avoiding an early exit out of contexts that do not properly account for it. It is replaced with a delayed, graceful soft OOM triggered at the next VM safe point, and an immediate hard OOM using `_exit()` if memory consumption reaches a second, higher threshold. The shutdown procedure will no longer see invalid state, and PHP's normal ability to limit memory consumption is retained.

> [!WARNING]
> Updating to a PHP release containing the patch to this vulnerability is the _only_ complete mitigation.

For installations that cannot update, setting and enforcing `memory_limit=-1` administratively is the primary configuration mitigation. It removes the predictable per-request limit that enables the confirmed exploit with a controllable OOM. This is not a complete mitigation. If `mmap()` or another underlying allocation fails, PHP can still use `longjmp()` while incomplete request memory is reachable. Restart every PHP worker and confirm that no pool, directory or application setting restores a finite PHP memory limit.

Keep `post_max_size` conservative and independently enforce the decoded request size at the frontend. Reduce `max_input_nesting_level`, and bound the number of input variables, multipart parts, headers within each part and uploads. These controls reduce hard OOM and denial of service risk even after applying the patch, but do not replace updating. If the application does not use multipart form data, block such requests at the frontend before they reach PHP.

A container or cgroup memory limit (`memory.max`) may provide an alternative to PHP's own `memory_limit` with some limitations. It is not guaranteed to prevent allocation failure and is not a complete mitigation. For example, killing a container or cgroup can also kill the master and every worker, unless each worker has its own group. Killing one FPM child fails only its current requests and FPM's master replaces it quickly. Do _not_ use `RLIMIT_AS` or `RLIMIT_DATA`, as these will cause `mmap()` to fail once the memory limit is reached, triggering the vulnerable `longjmp()` path.

**Important**: Make sure to also follow the remediation advice from the related report.
https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp

Conditions et limites — texte original PHP

### OOM strategies

Several multipart parsing problems can let a request reach OOM while remaining within its apparent PHP limits:

- A multipart request without a usable declared content length may pass the initial `post_max_size` check and continue supplying decoded body data.
- A multipart part can contain an unrestricted number of headers. Representing these headers inside PHP can use substantially more memory than their wire representation, allowing a request within `post_max_size` to exhaust the normal `memory_limit`.
- Empty file controls do not count towards `max_file_uploads` but still create the normal file metadata arrays. Nested field names multiply the generated array work.

OOM can also be reached in application-specific ways when attacker-controlled input causes a sufficiently large allocation or repeated memory use.

### Susceptibility

Apache mod_php unconditionally invokes the request shutdown procedure, even when request startup has failed. During request startup, automatic body parsing can exhaust the configured memory limit and exit the request in a context where state is temporarily invalid. Shutdown then processes this invalid state. This happens entirely before any application-specific code begins execution.

FPM exits the child when request startup fails. This prevents consumption of the invalid state and removes the child from the pool. After normal startup, OOM may still be reached in a context failing to account for an early exit, with the invalid state being processed during request shutdown. Source analysis therefore supports FPM as a susceptible, though no complete FPM exploit has been demonstrated for this SAPI.

Source analysis indicates that FrankenPHP, analogous to Apache mod_php, calls the request shutdown procedure unconditionally, making it likely susceptible to application-independent attacks. LSAPI models FPM, with application-specific exploits being likely but unvalidated.

PoC : attestation publique officielle de démonstration sous conditions ; code d’exploit public non vérifié. Exploitation en milieu naturel non établie par ces sources. Présence locale non établie.

CVSS 4.0 : 9.2 — CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N

Défiler vers le haut