Patchs, Dockerfiles, images Docker et outils de preuve pour les branches PHP qui n'ont pas reçu de
version corrigée. English version: [README.en.md](README.en.md).
1. Ce dépôt corrige CVE-2026-109618 et CVE-2026-109619 pour PHP 5.0 à 8.1. PHP n'a publié de version corrigée que pour 8.2.35, 8.3.36, 8.4.27 et 8.5.12.
2. Il s'adresse à toute entreprise qui exploite PHP 5.0 à 8.1 (FPM, mod_php, CGI ou CLI), que ce soit en image Docker, en paquet Debian, Ubuntu ou RHEL, ou en compilation depuis les sources.
3. Pour 7.4, 8.0 et 8.1, le code vient des branches de correctif officielles de php-src. Pour 5.0 à 7.3, ce sont des portages maison, que le projet PHP n'a ni relus ni approuvés.
4. 17 images sont construites: 5.0, 5.1 et 5.2 en CGI (`php-cgi -b 0.0.0.0:9000`), 5.3 à 8.1 en FPM, 7.4 sur deux bases (bullseye, et bookworm avec OpenSSL 3), plus deux images de version exacte, 5.6.9 et 5.4.36.
5. Ce qui est prouvé, par mesure du 2026-10-21: sur chacune des 17 images, après un dépassement de `memory_limit`, la phase de fin de requête ne s'exécute plus (`test-image.sh`, verdict CORRIGE). Les images officielles passées au même test (`php:5.4-fpm`, `php:5.5-fpm`, `php:5.6-fpm`, `php:7.4-fpm-bullseye`, `php:8.0-fpm-bullseye`) restent NON CORRIGE.
6. Ce qui est prouvé aussi: les 17 images passent la recette fonctionnelle (`test-fonctionnel.sh`, 30 épreuves) sans aucun ECHEC. 13 d'entre elles sont comparées à l'image officielle de même version. Pour 5.0 à 5.3, il n'existe pas d'image officielle et seuls les contrôles propres à l'image sont joués. L'extension openssl de 7.4 sur bookworm est testée en plus (`test-openssl.sh`).
7. Ce qui n'est pas prouvé: le second chemin (upload progress de session par POST multipart via FPM, CVE-2026-109619). Les tests ne l'exercent pas. Le correctif est présent dans le code, mais son effet n'a pas été mesuré.
8. Pas d'image pour 5.5.9. Le patch adapté existe (`patches/cve-559-portage.patch`), mais Docker Hub n'a pas d'image officielle `php:5.5.9-fpm` qui servirait de base et de témoin. Ce patch n'a été ni compilé ni testé.
9. Les bases Debian sont hors support, sauf bookworm. Chaque image expire 90 jours après sa construction (label `php-fixed.expires`), soit le 2027-01-19 pour cette construction, et doit être reconstruite avant cette date.
10. Seules ces deux CVE sont corrigées. Les autres failles de ces versions en fin de vie restent ouvertes, et la seule issue durable est de migrer vers une branche maintenue. Si vous ne pouvez pas utiliser les images, la section 5 explique appliquer le patch à vos propres builds et paquets, et la section 6 donne des mesures provisoires.
- **Source du correctif**: « officielle » désigne une branche php-src `PHP-X.Y-CVE-2026-109618-109619`, « maison » un portage écrit pour ce dépôt.
- **S'applique sur**: les versions sur lesquelles l'application du patch est constatée. Pour 7.4, 8.0 et 8.1, c'est `git apply --check` sur la version indiquée, où le patch s'applique tel quel. Pour 7.0 à 7.3, c'est `git apply` sur le tag php-src. Pour les images 5.x, c'est `patch -p1 --fuzz=0` pendant la construction.
- **Preuve CVE**: le verdict de `test-image.sh` consigné dans `manifeste.txt`, et celui du témoin quand il a été passé au même test (`journaux/preuves-2026-10-21-durci.txt`, `journaux/exposition-php5-officielles.txt`).
- **Témoin**: l'image officielle `php:` de même version, non corrigée, qui sert de référence.
- **Recette fonctionnelle**: le bilan de `outils/test-fonctionnel.sh`, détaillé dans `journaux/fonctionnel-.txt`.
| Version | Source du correctif | Patch | S'applique sur | Image Docker | Preuve CVE | Recette fonctionnelle |
| 8.1 | officielle, `PHP-8.1-CVE-2026-109618-109619` | `patches/cve-81.patch` (diff de référence, l'image est construite depuis la branche) | 8.1.33; la branche donne PHP 8.1.34 dans l'image | `php-fixed:8.1-fpm` (bookworm) | CORRIGE; témoin `php:8.1-fpm-bookworm` non passé à `test-image.sh` | 0 ECHEC contre `php:8.1-fpm-bookworm` |
| 8.0 | officielle, `PHP-8.0-CVE-2026-109618-109619` | `patches/cve-80.patch` (diff de référence) | 8.0.30; PHP 8.0.30 dans l'image | `php-fixed:8.0-fpm` (bullseye) | CORRIGE; témoin `php:8.0-fpm-bullseye` NON CORRIGE | 0 ECHEC contre `php:8.0-fpm-bullseye` |
| 7.4 | officielle, `PHP-7.4-CVE-2026-109618-109619` | `patches/cve-74.patch` (diff php-7.4.33 -> branche, hors `php_version.h`, `configure.ac`, `NEWS`) | 7.4.33 (base du diff) et 7.4.29; PHP 7.4.34-dev dans l'image | `php-fixed:7.4-fpm-bullseye` | CORRIGE; témoin `php:7.4-fpm-bullseye` NON CORRIGE | 0 ECHEC contre `php:7.4-fpm-bullseye` |
| 7.4 (OpenSSL 3) | officielle + `patches/openssl3-74.patch` (maison) | `cve-74.patch` + `openssl3-74.patch` | comme ci-dessus | `php-fixed:7.4-fpm-bookworm` | CORRIGE | 0 ECHEC contre `php:7.4-fpm-bullseye` (pas d'image officielle 7.4 sur bookworm) |
| 7.3 | maison | `patches/cve-73-portage.patch` | 7.3.33 | `php-fixed:7.3-fpm-bullseye-portage` | CORRIGE; témoin `php:7.3-fpm-bullseye` non passé à `test-image.sh` | 0 ECHEC contre `php:7.3-fpm-bullseye` |
| 7.2 | maison | `patches/cve-72-portage.patch` | 7.2.34 | `php-fixed:7.2-fpm-bullseye-portage` | CORRIGE; témoin `php:7.2-fpm-buster` non passé à `test-image.sh` | 0 ECHEC contre `php:7.2-fpm-buster` |
| 7.1 | maison | `patches/cve-71-portage.patch` | 7.1.33 | `php-fixed:7.1-fpm-bullseye-portage` | CORRIGE; témoin `php:7.1-fpm` non passé à `test-image.sh` | 0 ECHEC contre `php:7.1-fpm` |
| 7.0 | maison | `patches/cve-70-portage.patch` | 7.0.33 | `php-fixed:7.0-fpm-bullseye-portage` | CORRIGE; témoin `php:7.0-fpm` non passé à `test-image.sh` | 0 ECHEC contre `php:7.0-fpm` |
| 5.6 | maison | `patches/cve-56-portage.patch` | 5.6.40 | `php-fixed:5.6-fpm-stretch-portage` | CORRIGE; témoin `php:5.6-fpm` NON CORRIGE | 0 ECHEC contre `php:5.6-fpm` |
| 5.6.9 | maison, variante de version exacte | `patches/cve-569-portage.patch` | 5.6.9 | `php-fixed:5.6.9-fpm-jessie-portage` | CORRIGE; témoin `php:5.6.9-fpm` non passé à `test-image.sh` | 0 ECHEC contre `php:5.6.9-fpm` |
| 5.5 | maison | `patches/cve-55-portage.patch` | 5.5.38 | `php-fixed:5.5-fpm-jessie-portage` | CORRIGE; témoin `php:5.5-fpm` NON CORRIGE | 0 ECHEC contre `php:5.5-fpm` |
| 5.5.9 | maison, variante de version exacte | `patches/cve-559-portage.patch` | adapté à 5.5.9, ni compilé ni testé | aucune: pas d'image `php:5.5.9-fpm` sur Docker Hub | aucune, faute d'image | aucune, faute d'image |
| 5.4 | maison | `patches/cve-54-portage.patch` | 5.4.45 | `php-fixed:5.4-fpm-jessie-portage` | CORRIGE; témoin `php:5.4-fpm` NON CORRIGE | 0 ECHEC contre `php:5.4-fpm` |
| 5.4.36 | maison, variante de version exacte | `patches/cve-5436-portage.patch` | 5.4.36 | `php-fixed:5.4.36-fpm-jessie-portage` | CORRIGE; témoin `php:5.4.36-fpm` non passé à `test-image.sh` | 0 ECHEC contre `php:5.4.36-fpm` |
| 5.3 | maison | `patches/cve-53-portage.patch` | 5.3.29 | `php-fixed:5.3-fpm-jessie-portage` | CORRIGE; pas d'image officielle | 0 ECHEC, contrôles propres à l'image |
| 5.2 | maison | `patches/cve-52-portage.patch` | 5.2.17 | `php-fixed:5.2-cgi-jessie-portage` (CGI) | CORRIGE; pas d'image officielle | 0 ECHEC, contrôles propres à l'image |
| 5.1 | maison | `patches/cve-51-portage.patch` | 5.1.6 | `php-fixed:5.1-cgi-jessie-portage` (CGI) | CORRIGE; pas d'image officielle | 0 ECHEC, contrôles propres à l'image |
| 5.0 | maison | `patches/cve-50-portage.patch` | 5.0.5 | `php-fixed:5.0-cgi-jessie-portage` (CGI) | CORRIGE; pas d'image officielle | 0 ECHEC, contrôles propres à l'image |
Les témoins notés « non passé à `test-image.sh` » ont été comparés en recette fonctionnelle. Leurs sources
sous `/usr/src` ne contiennent pas le correctif: l'épreuve `sources-patchees` n'y trouve aucune occurrence
Les empreintes sha256 des patchs sont dans `journaux/patches.sha256`. Les tags `php-fixed:...` sont les noms
locaux produits par `outils/build.sh`. Pour les noms publiés, voir `docs/publication-docker.md`.
De 5.0 à 5.3, la partie « session » de CVE-2026-109619 est sans objet, parce que l'upload progress de
session n'existe qu'à partir de PHP 5.4.0. Les autres parties du correctif s'appliquent.
**Images CGI (5.0, 5.1 et 5.2).** PHP-FPM n'existe qu'à partir de PHP 5.3. Ces images lancent donc
`php-cgi -b 0.0.0.0:9000`, un serveur FastCGI sur le même port que les images FPM. Comme l'image officielle,
l'image tourne en root. `php-cgi` ne change pas d'utilisateur de lui-même: c'est l'entrypoint qui l'abaisse
### Comparaison avec les images officielles
Résultat de `outils/test-fonctionnel.sh` pour chaque image (source: `journaux/tableau-comparatif.md`).
| Image php-fixed | Témoin officiel | Correctif CVE (`test-image.sh`) | Recette fonctionnelle | Modules | Configure | FPM/CGI sert | `docker-php-ext-install` | Labels |
| `php-fixed:5.0-cgi-jessie-portage` | aucun | CORRIGE | 16 OK, 14 INFO, 0 ECHEC | INFO | INFO | OK | OK | OK |
| `php-fixed:5.1-cgi-jessie-portage` | aucun | CORRIGE | 16 OK, 14 INFO, 0 ECHEC | INFO | INFO | OK | OK | OK |
| `php-fixed:5.2-cgi-jessie-portage` | aucun | CORRIGE | 17 OK, 13 INFO, 0 ECHEC | INFO | INFO | OK | OK | OK |
| `php-fixed:5.3-fpm-jessie-portage` | aucun | CORRIGE | 20 OK, 10 INFO, 0 ECHEC | INFO | INFO | OK | OK | OK |
| `php-fixed:5.4-fpm-jessie-portage` | `php:5.4-fpm` | CORRIGE | 23 OK, 7 INFO, 0 ECHEC | OK | OK | OK | OK | OK |
| `php-fixed:5.4.36-fpm-jessie-portage` | `php:5.4.36-fpm` | CORRIGE | 23 OK, 7 INFO, 0 ECHEC | OK | OK | OK | OK | OK |
| `php-fixed:5.5-fpm-jessie-portage` | `php:5.5-fpm` | CORRIGE | 23 OK, 7 INFO, 0 ECHEC | OK | OK | OK | OK | OK |
| `php-fixed:5.6-fpm-stretch-portage` | `php:5.6-fpm` | CORRIGE | 25 OK, 5 INFO, 0 ECHEC | OK | OK | OK | OK | OK |
| `php-fixed:5.6.9-fpm-jessie-portage` | `php:5.6.9-fpm` | CORRIGE | 23 OK, 7 INFO, 0 ECHEC | OK | OK | OK | OK | OK |
| `php-fixed:7.0-fpm-bullseye-portage` | `php:7.0-fpm` | CORRIGE | 25 OK, 5 INFO, 0 ECHEC | OK | OK | OK | OK | OK |
| `php-fixed:7.1-fpm-bullseye-portage` | `php:7.1-fpm` | CORRIGE | 25 OK, 5 INFO, 0 ECHEC | OK | OK | OK | OK | OK |
| `php-fixed:7.2-fpm-bullseye-portage` | `php:7.2-fpm-buster` | CORRIGE | 25 OK, 5 INFO, 0 ECHEC | OK | OK | OK | OK | OK |
| `php-fixed:7.3-fpm-bullseye-portage` | `php:7.3-fpm-bullseye` | CORRIGE | 25 OK, 5 INFO, 0 ECHEC | OK | OK | OK | OK | OK |
| `php-fixed:7.4-fpm-bookworm` | `php:7.4-fpm-bullseye` | CORRIGE | 24 OK, 6 INFO, 0 ECHEC | OK | OK | OK | OK | OK |
| `php-fixed:7.4-fpm-bullseye` | `php:7.4-fpm-bullseye` | CORRIGE | 24 OK, 6 INFO, 0 ECHEC | OK | OK | OK | OK | OK |
| `php-fixed:8.0-fpm` | `php:8.0-fpm-bullseye` | CORRIGE | 25 OK, 5 INFO, 0 ECHEC | OK | OK | OK | OK | OK |
| `php-fixed:8.1-fpm` | `php:8.1-fpm-bookworm` | CORRIGE | 25 OK, 5 INFO, 0 ECHEC | OK | OK | OK | OK | OK |
- **Modules** et **Configure**: `php -m` et la ligne de configure sont identiques à ceux du témoin. INFO signifie qu'il n'existe pas d'image officielle pour cette branche (5.0 à 5.3): seuls les contrôles propres à l'image sont joués.
- **FPM/CGI sert**: derrière nginx, FPM (ou `php-cgi -b` pour 5.0 à 5.2) répond à deux requêtes par un HTTP 200. La session est relue, un fichier temporaire est écrit puis relu, et le journal ne contient aucun avertissement.
- **`docker-php-ext-install`**: une extension est compilée sans réseau contre les sources patchées de l'image, puis chargée sans avertissement.
- **Labels**: les labels de provenance sont renseignés, et l'expiration est au 2027-01-19.
### `test-image.sh `: le chemin exploité, en deux épreuves
Le script lance `php -d memory_limit=4M` avec une fonction enregistrée par `register_shutdown_function`, puis
- **chaîne**: une seule allocation de 64 Mo (`str_repeat`);
- **tableau**: un tableau qui grandit élément par élément, donc des réallocations successives.
- **NON CORRIGE**: la fonction de fin de requête s'exécute après le dépassement. C'est le chemin exploité par CVE-2026-109618. Mesuré: code de sortie 255.
- **CORRIGE**: le message `Allowed memory size ... exhausted` part sur stderr, le processus s'arrête aussitôt (`_exit(1)`, code 1) et la fonction de fin ne s'exécute pas.
- **DEFAUT**: tout autre cas. Un plantage (code 139, SIGSEGV) n'est jamais compté comme une correction. Une première version du script le comptait comme tel, et un portage 7.0 qui plantait est passé pour CORRIGE avant d'être corrigé (`journaux/preuves-2026-10-21.txt`, puis `journaux/preuves-2026-10-21-durci.txt`).
Le verdict global est le pire des deux. Le script n'a besoin que de `docker` et `bash`, et il est écrit en
syntaxe PHP 5.0 (`array()`, fonction nommée), ce qui permet de le jouer sur toutes les versions.
### `outils/test-fonctionnel.sh []`: l'image corrigée remplace-t-elle l'officielle?
Chaque image passe 30 épreuves, comparées à l'image officielle de même version quand elle existe. Chaque
épreuve rend OK, ECHEC ou INFO. Les 17 images ont 0 ECHEC, avec 16 à 25 OK; le reste est en INFO. Les INFO
sont plus nombreux pour 5.0 à 5.3, faute de témoin officiel. Les épreuves couvrent:
- l'identité: `php -v`, la ligne de configure, les fichiers ini, l'entrypoint, l'utilisateur `www-data`;
- FPM, ou `php-cgi -b` pour 5.0 à 5.2, en fonctionnement réel derrière nginx, sur un réseau Docker interne: session, json, journaux, avertissements;
- l'outillage: sources patchées sous `/usr/src`, `docker-php-ext-install`, pecl;
- les labels, la taille et le nombre de couches.
Les résultats sont dans `journaux/fonctionnel-.txt` et sont résumés dans le tableau de la section 2.
`outils/test-tous-fonctionnels.sh` les enchaîne.
La recette a trouvé quatre défauts. Ils ont été corrigés et les images reconstruites avant les mesures
- FPM ne démarrait pas sur 7.0, 7.1 et 7.2: les Dockerfiles reprenaient la configuration FPM de 7.3, avec des directives inconnues des versions antérieures. Ils ont été refaits à partir du Dockerfile officiel de chaque version.
- Sur 5.4.36, la purge des outils de construction retirait aussi des paquets de la base, dont `libc6-dev`, et `docker-php-ext-install` échouait. La purge épargne désormais tous les paquets de la base, dont la liste est conservée dans `/usr/src/paquets-base.txt`.
- Sur 8.1, le chemin d'inclusion des pools FPM était faux (`NONE/etc/php-fpm.d`) après l'alignement de la ligne de configure sur l'image officielle publiée. FPM ne démarrait pas.
- Les images CGI tournaient en `www-data`, ce qui empêchait `docker-php-ext-install` dans une image dérivée. Elles tournent maintenant en root comme l'officielle, et `php-cgi` est abaissé en `www-data` au lancement.
### `outils/test-openssl.sh `: 7.4 sur bookworm (OpenSSL 3)
PHP 7.4 n'a pas été écrit pour OpenSSL 3. L'image `7.4-fpm-bookworm` ajoute `patches/openssl3-74.patch`.
Résultat mesuré: 16 OK, 8 INFO, 0 ECHEC (`journaux/test-openssl-74-bookworm.txt`, contre
`journaux/test-openssl-74-bullseye.txt` en OpenSSL 1.1.1). Les épreuves couvrent AES-CBC et GCM, la signature
et le chiffrement RSA, EC P-256, X.509, PBKDF2, `openssl_seal` avec AES et TLS 1.3.
- **Second chemin non exercé.** Aucun test n'envoie de POST multipart via FPM avec le champ `PHP_SESSION_UPLOAD_PROGRESS`. Un client FastCGI de départ existe (`outils/fcgi_multipart.py`), mais il ne fait partie d'aucune preuve publiée.
- **Portages non officiels.** Les patchs 5.0 à 7.3 sont un travail maison. Ils reprennent les intentions du correctif officiel 7.4, mais personne au projet PHP ne les a relus. La suite de tests de PHP (`make test`) n'a pas été jouée sur ces portages.
- **PHP 5.0 et 5.1.** `memory_limit` n'y existe que si PHP a été compilé avec `--enable-memory-limit`. Les images 5.0 et 5.1 sont construites avec cette option. Sur votre binaire, vérifiez `php -i | grep memory_limit`. Sans cette option, il n'y a pas de limite mémoire, donc pas de chemin à corriger, et `test-image.sh` n'a rien à tester.
- **Bases Debian archivées.** jessie (5.x), stretch (5.6) et bullseye (7.0 à 8.0) sont hors support: le label `php-fixed.base.eol` donne la date de fin, et pour bullseye c'est le 2026-08-31. Leurs paquets viennent d'archive.debian.org, sans mises à jour de sécurité. Pour les images 5.x, si la signature de l'archive ne peut plus être vérifiée, la construction passe en `[trusted=yes]` et le consigne dans `/usr/src/php-fixed-apt.txt`. Une signature invalide reste une erreur. Seul bookworm (7.4-bookworm, 8.1) est maintenu, jusqu'au 2028-06-30.
- **Expiration à 90 jours.** Chaque image porte `php-fixed.expires`, c'est-à-dire la date de construction plus 90 jours. Pour les images du manifeste actuel, c'est le 2027-01-19. Au-delà, reconstruisez avec `outils/build.sh`, qui reprend les derniers paquets de la base et le dernier commit des branches officielles.
- **OpenSSL 3 sur 7.4 bookworm.** Les algorithmes « legacy » ne sont pas disponibles sans le provider legacy: rc4, des-cbc, des-ecb, bf-cbc, cast5-cbc, rc2-cbc, seed-cbc, md4. `openssl_seal` sans méthode (rc4 par défaut en 7.4) échoue aussi. Si votre application en dépend, prenez `7.4-fpm-bullseye`. Le fonctionnement avec le provider legacy activé n'a pas été testé.
- **Changement de comportement après un dépassement de mémoire**, identique à celui du correctif officiel. Le message ne passe plus par le gestionnaire d'erreurs de PHP, donc rien n'arrive dans `error_log`: il part sur stderr. Le processus FPM s'arrête et le maître en relance un autre. Pour conserver ce message, gardez `catch_workers_output = yes` dans le pool. La réponse HTTP que reçoit alors le client (une 502 du proxy, par exemple) n'a pas été mesurée.
- **Variable `PHP_VERSION`.** Sur les images 7.x et 8.x, la variable d'environnement `PHP_VERSION` porte un suffixe, par exemple `8.0.30-cve-2026-109618-109619` ou `7.3.33-cve-2026-109618-109619-portage`. Elle diffère donc de celle de l'image officielle. Vérifiez les scripts qui lisent cette variable. Sur `8.1-fpm`, elle vaut `8.1.33-cve-2026-109618-109619` alors que le binaire est en 8.1.34. Sur les deux images 7.4, elle vaut `7.4.33-cve-2026-109618-109619` pour un binaire en 7.4.34-dev, qui est la version de la branche.
- **Architecture.** Les images ont été construites et testées sur un hôte x86_64 uniquement. Aucune autre architecture n'a été testée.
1. Remplacez l'image officielle par l'image corrigée de même version:
# après (nom local; nom publié: /:8.0-fpm, voir docs/publication-docker.md)
Les chemins, la configuration FPM et les scripts `docker-php-*` sont ceux de l'image officielle.
`docker-php-ext-install` compile vos extensions contre les sources patchées (`/usr/src/php.tar.xz`).
docker inspect -f '{{range $k, $v := .Config.Labels}}{{$k}}={{$v}}{{"\n"}}{{end}}' php-fixed:8.0-fpm \
| grep -E '^(php-fixed|org\.opencontainers)'
- `php-fixed.patch.sha256` est égal à la ligne du patch dans `journaux/patches.sha256`;
- `org.opencontainers.image.revision` est le commit php-src annoncé, pour les branches officielles.
3. Rejouez la preuve sur **votre** image, c'est-à-dire celle qui part en production avec vos couches, et sur
votre témoin, l'image officielle que vous utilisez aujourd'hui:
./test-image.sh mon-registre/mon-app:candidate # attendu: verdict global CORRIGE
./test-image.sh php:8.0-fpm # attendu: verdict global NON CORRIGE
outils/test-fonctionnel.sh mon-registre/mon-app:candidate php:8.0-fpm
Si votre témoin ne sort pas NON CORRIGE, la preuve ne dit rien sur votre environnement. Cherchez
## 5. Appliquer le patch à votre propre build
Choisissez le patch dans le tableau de la section 2: celui de la branche, ou la variante de version exacte
si elle existe (`cve-569-portage.patch` pour 5.6.9, `cve-5436-portage.patch` pour 5.4.36,
`cve-559-portage.patch` pour 5.5.9, ce dernier ni compilé ni testé). `cve-74.patch` s'applique tel quel sur
7.4.29 comme sur 7.4.33. Les patchs sont des diffs git (`a/` et `b/`) et s'appliquent avec `-p1` sur
tar -xf php-7.4.33.tar.xz # archive de php.net (museum.php.net pour les versions anciennes)
patch -p1 --dry-run && make && make install
- Si `patch` signale un décalage (« offset ») ou un « fuzz », vérifiez à la main le bloc concerné. Si un bloc est refusé, le patch ne convient pas à cette version.
- Les patchs 7.0 à 7.3 contiennent déjà le fichier `Zend/zend_vm_execute.h` régénéré, il n'y a rien à régénérer.
- Pour 5.0 et 5.1, ajoutez `--enable-memory-limit`.
- Après l'installation, rejouez la preuve sur le binaire obtenu: voir [docs/rebuild-paquets.md](docs/rebuild-paquets.md), section « Vérifier un binaire local ».
Pour les paquets Debian, Ubuntu, RHEL, AlmaLinux et Rocky Linux, la procédure (`apt-get source`, quilt,
`dpkg-buildpackage`, `rpmbuild`) est dans [docs/rebuild-paquets.md](docs/rebuild-paquets.md). Un paquet de
distribution embarque souvent ses propres correctifs rétroportés. Ce dépôt n'a vérifié l'application du
patch sur aucun paquet de distribution: elle se constate paquet par paquet.
## 6. Mesures provisoires si vous ne pouvez pas patcher
Aucune de ces mesures ne remplace le correctif: elles réduisent l'exposition.
| Mesure | Versions | Ce qu'elle couvre | Limites |
| `session.upload_progress.enabled=0` posé par `php_admin_flag` | 5.4 et plus | la surface session de CVE-2026-109619: le correctif officiel rend ce rappel inerte, et ce réglage coupe le même test d'entrée | ne couvre pas CVE-2026-109618 (OOM puis fin de requête); le réglage est PERDIR, donc sans `php_admin_*`, un `.user.ini` ou un `.htaccess` peut le réactiver; les barres de progression d'upload ne fonctionnent plus |
| `post_max_size` bas, `max_input_vars` et `max_file_uploads` bas | selon la version (`max_file_uploads` à partir de 5.3.1, `max_input_vars` à partir de 5.3.9) | l'amplification mémoire par les variables d'entrée | au-delà de `max_input_vars`, l'analyse multipart continue; ne coupe pas le chemin OOM |
| `max_multipart_body_parts` bas | versions qui le connaissent (vérifier par `php -i`) | le nombre de parties multipart analysées | absent des versions anciennes |
| `enable_post_data_reading=0` sur les pools qui ne lisent pas de formulaires | 5.4 et plus | plus d'analyse multipart du tout | plus de `$_POST` ni de `$_FILES`: réservé aux API qui lisent `php://input` |
| Multipart bloqué en amont (proxy, WAF) quand l'application n'en a pas besoin, ou requêtes contenant `PHP_SESSION_UPLOAD_PROGRESS` refusées | toutes | le second chemin | dépend de l'application; un filtre qui lit mal le multipart se contourne |
| Limite mémoire du conteneur ou du cgroup | toutes | protège l'hôte des conséquences | ne supprime pas la faille, parce que `memory_limit` est atteint avant la limite du conteneur |
| Isolation: FPM joignable seulement par le proxy, applications anciennes derrière authentification ou VPN | toutes | réduit le nombre d'attaquants possibles | ne corrige rien |
Pool FPM (fichier lu après les autres, par exemple `/usr/local/etc/php-fpm.d/zz-attenuation.conf`). Les
php_admin_flag[session.upload_progress.enabled] = off
Apache avec mod_php (vhost ou ``, pas `.htaccess`):
php_admin_flag session.upload_progress.enabled off
nginx, pour un site qui ne reçoit jamais de formulaire multipart:
if ($http_content_type ~* "multipart/form-data") { return 415; }
Vérifiez l'effet par une page `phpinfo()` servie par le pool concerné. `php -i` en ligne de commande ne lit
- Docker avec BuildKit. `outils/build.sh` exporte `DOCKER_BUILDKIT=1`, et les fichiers `build*/Dockerfile.dockerignore` l'exigent.
- `bash`, `git`, `curl` et `sha256sum` sur l'hôte. Pour les branches officielles, `build.sh` résout le commit avec `git ls-remote` avant de construire, et le Dockerfile refuse de construire si le commit cloné diffère.
- Un accès réseau à github.com, archive.debian.org, Docker Hub et museum.php.net.
- Pour 5.0 à 5.3: les archives sources officielles, vérifiées par empreinte. Si museum.php.net ne répond pas, déposez l'archive sous `build5N/` et elle est prise à la place du téléchargement, avec la même vérification.
| `php-5.3.29.tar.xz` | `8438c2f14ab8f3d6cd2495aa37de7b559e33b610f9ab264f0c61b531bf0c262d` | museum.php.net, identique à php.net |
| `php-5.2.17.tar.bz2` | `e81beb13ec242ab700e56f366e9da52fd6cf18961d155b23304ca870e53f116c` | museum.php.net, identique à php.net |
| `php-5.1.6.tar.bz2` | `3e9510ce715f28b7e6b803fcdadb73b37c83792c0b5e1e9bcb066ab972649996` | museum.php.net seul (php.net ne publie pas d'empreinte) |
| `php-5.0.5.tar.bz2` | `aa63e769059d2452b153db6d4e6b421228d0606cbe8b11ace00e4c1b5c2cdc4f` | museum.php.net seul (php.net ne publie pas d'empreinte) |
### Reconstruire les patchs (sources 7.0 à 7.3)
Les images 7.0 à 7.3 partent d'une archive `build7N/php.tar.xz` déjà patchée. Cette archive n'est pas
git clone src/php-src-cve
git worktree add --detach wt73 php-7.3.33 # 7.0.33, 7.1.33, 7.2.34, 7.3.33
git -C wt73 apply ../../patches/cve-73-portage.patch
tar -cJf ../../build73/php.tar.xz --exclude=.git --transform 's,^wt73,php,' wt73
outils/build.sh --liste # cibles et images produites
outils/build.sh 74 80 81 # quelques cibles
PHP_SHA256_53=8438c2f14ab8f3d6cd2495aa37de7b559e33b610f9ab264f0c61b531bf0c262d outils/build.sh 53
IMAGE_SOURCE= outils/build.sh # toutes, avec l'URL publique en label
outils/test-tous-fonctionnels.sh # recette fonctionnelle de toutes les images locales
`build.sh` construit chaque cible, joue `test-image.sh`, puis met à jour `manifeste.txt`. Le journal de
chaque construction est `journaux/build.log`. Le script ne rend 0 que si toutes les cibles demandées
- **Labels OCI**: `org.opencontainers.image.*`, soit `created`, `revision`, `source`, `base.name`, `base.digest`, `version`, `authors` et `vendor`.
- **Labels propres**: `php-fixed.cve`, `php-fixed.patch`, `php-fixed.patch.sha256`, `php-fixed.source` et `php-fixed.source.branch` (branches officielles), `php-fixed.patch.openssl3` et `php-fixed.patch.openssl3.sha256` (7.4 bookworm), `php-fixed.php.eol`, `php-fixed.base.eol` et `php-fixed.expires`.
- `/usr/src/php-src-commit.txt`: pour les branches officielles, le commit, la date et le titre; pour les portages, le patch et son empreinte;
- `/usr/src/`: le patch appliqué, pour les portages et pour `openssl3-74.patch`;
- `/usr/src/php.tar.xz`: les sources patchées;
- pour 5.x: `/usr/src/php-fixed-apt.txt`, l'état des dépôts apt (authentifiés ou `[trusted=yes]`);
- pour 5.4, 5.5 et 5.6 (dont 5.4.36 et 5.6.9): `/usr/src/paquets-base.txt`, la liste des paquets de l'image de base, que la purge des outils de construction épargne.
- **`manifeste.txt`**: une ligne par image, au format `image | id | PHP_VERSION | base@digest | sha256 du patch | date | verdict`.
docker run --rm --entrypoint cat php-fixed:7.3-fpm-bullseye-portage /usr/src/php-src-commit.txt
docker run --rm --entrypoint sh php-fixed:7.3-fpm-bullseye-portage -c 'sha256sum /usr/src/*.patch'
Auteur: Khalil Rabah , IBNM Engineering, Les licences sont détaillées
- les fichiers propres au dépôt (scripts, Dockerfiles, documentation, apports des portages) sont sous licence MIT;
- les portions dérivées de php-src restent sous PHP License 3.01 (3.0 pour PHP 5.0);
- les portions dérivées de docker-library/php restent sous licence MIT.
Ce projet n'est ni affilié au PHP Group ni approuvé par lui. Pour signaler un problème, voir
- Le projet php-src (The PHP Group), pour les branches de correctif `PHP-7.4`, `PHP-8.0` et `PHP-8.1-CVE-2026-109618-109619`, utilisées telles quelles pour ces trois versions et prises comme référence pour les portages.
- docker-library/php, pour les Dockerfiles et les scripts `docker-php-*` dont dérivent les Dockerfiles de ce dépôt (copies d'origine dans `dockerfiles-officiels/`).
The full story
This article is one source in a clustered incident — the cluster page carries the summary, timeline and every other outlet covering it.
