Le 10 mai 2026, l'équipe PHP a publié simultanément des correctifs pour trois vulnérabilités CRITICAL (CVSS 9.8) affectant toutes les branches PHP 8.2.x, 8.3.x, 8.4.x et 8.5.x. Deux concernent l'extension SOAP (use-after-free menant à de la corruption mémoire et potentiellement à du RCE), une concerne le driver PDO Firebird (SQL injection via NUL byte). Vu l'ubiquité de PHP dans l'écosystème web (WordPress, Drupal, Magento, Laravel, Symfony…), c'est une mise à jour à déployer en priorité absolue.
Les versions corrigées sont : 8.2.31, 8.3.31, 8.4.21, 8.5.6.
Vue d'ensemble
| CVE | Composant | Type | CVSS | Conditions d'exploitation |
|---|---|---|---|---|
| CVE-2025-14179 | PDO Firebird driver | SQL injection (NUL byte) | 9.8 | Utilisation de PDO::quote() avec valeurs attaquant-controlled |
| CVE-2026-6722 | SOAP — déduplication d'objets | Use-after-free → RCE | 9.8 | SoapServer recevant des requêtes SOAP avec apache:Map dupliqués |
| CVE-2026-7261 | SOAP — session persistence | Use-after-free | 9.8 | SoapServer configuré avec SOAP_PERSISTENCE_SESSION |
CVE-2025-14179 — PDO Firebird : NUL byte breaks PDO::quote()
Le bug
Quand le driver Firebird de PDO construit une requête token par token, un token chaîne contenant un NUL byte (\0) est copié via strncat(). Or strncat() s'arrête au premier NUL — la copie tronque la chaîne, la quote fermante n'est pas écrite, et les tokens SQL suivants sont interprétés comme partie de la chaîne ouverte.
Concrètement, ça transforme :
SELECT * FROM users WHERE name = 'attacker\0' AND role = 'admin'
en :
SELECT * FROM users WHERE name = 'attacker' AND role = 'admin
↑
ouverture de chaîne non fermée
→ injection possible
Toute valeur attaquant-controlled passée à PDO::quote() avant intégration dans une requête SQL ouvre une injection SQL classique.
Conditions d'exploitation
- Application PHP utilisant le driver PDO Firebird (vendeur de base de données Firebird/Interbase)
- Utilisation de
PDO::quote()au lieu de prepared statements paramétrés - Capacité pour l'attaquant d'injecter un NUL byte dans la valeur (souvent possible via certains encodages, headers HTTP customs, ou champs binaires)
Mitigation immédiate
Au-delà du patch, migrer vers les prepared statements :
// VULNÉRABLE
$query = "SELECT * FROM users WHERE name = " . $pdo->quote($input);
$pdo->query($query);
// SÛR — prepared statement
$stmt = $pdo->prepare("SELECT * FROM users WHERE name = ?");
$stmt->execute([$input]);
C'est la mitigation correcte et durable, indépendamment de cette CVE.
CVE-2026-6722 — SOAP : use-after-free via déduplication d'objets dupliqués
Le bug
L'extension SOAP de PHP utilise un mécanisme de déduplication d'objets : pendant le parsing d'une requête SOAP, les pointeurs vers les objets PHP sont stockés dans une map globale sans incrémenter leur compteur de références.
Quand un nœud apache:Map contient des clés dupliquées, le traitement de la seconde entrée écrase la première dans le map temporaire de résultats, libérant l'objet PHP original tout en laissant son pointeur obsolète dans la map. Une référence href ultérieure au nœud libéré copie alors le pointeur dangling dans le résultat.
Du UAF au RCE
L'allocation de chaînes PHP peut réutiliser la zone mémoire libérée. Un attaquant contrôlant le contenu de la requête SOAP peut donc :
- Forcer la libération de l'objet (via clés dupliquées)
- Allouer une chaîne PHP de taille équivalente pour occuper la zone
- Y placer un objet contrefait (avec pointeur de classe vers une vtable malveillante)
- Déclencher l'appel d'une méthode sur le pointeur dangling → RCE
Vector typique : AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H (aucune authentification, exploitation réseau).
Conditions d'exploitation
- SoapServer PHP exposé HTTP/HTTPS
- Acceptation des requêtes SOAP avec corps contrôlés par l'attaquant (cas standard)
- Aucune authentification ni interaction utilisateur requise
CVE-2026-7261 — SOAP : use-after-free sur SOAP_PERSISTENCE_SESSION
Le bug
Quand SoapServer est configuré avec SOAP_PERSISTENCE_SESSION, l'objet handler est persisté entre les requêtes via le stockage de session. Si une requête SOAP génère une erreur, la logique de persistance est mal gérée : l'objet est libéré tout en conservant un pointeur vers lui dans la session.
Une requête suivante du même client réutilise le pointeur dangling, menant à :
- Corruption mémoire
- Information disclosure
- Crash du processus PHP
Selon l'allocateur, exploitation possible en RCE comme CVE-2026-6722 mais moins automatique.
Conditions d'exploitation
- SoapServer configuré avec
SOAP_PERSISTENCE_SESSION(cas courant pour les APIs SOAP stateful) - Possibilité pour l'attaquant de provoquer une erreur sur une requête puis d'envoyer une seconde requête
Produits et versions affectés
| Branche PHP | Versions affectées | Version corrigée |
|---|---|---|
| 8.2.x | < 8.2.31 | 8.2.31 |
| 8.3.x | < 8.3.31 | 8.3.31 |
| 8.4.x | < 8.4.21 | 8.4.21 |
| 8.5.x | < 8.5.6 | 8.5.6 |
PHP 8.1 et antérieures sont fin de support et ne reçoivent pas de patch officiel — toute installation sur ces versions est définitivement vulnérable.
Vérification de votre version
# Local
php -v
# Sur un serveur
ssh server "php -v"
# Dans un conteneur Docker
docker exec mon-app php -v
# Modules chargés (vérifier si SOAP et PDO Firebird sont actifs)
php -m | grep -E "soap|pdo_firebird"
Détection et IOC
Logs PHP
Surveillez /var/log/php/error.log (ou équivalent) :
- Erreurs SoapFault ou warnings dans
SoapServer::handle - Crashes de processus PHP-FPM (segfaults visibles dans
dmesgou les logs systemd) - Apparition d'objets PHP "déréférencés" dans les stacktraces
Logs serveur web
# Requêtes SOAP suspectes (apache:Map avec clés répétées)
grep -E "POST.*\.wsdl|Content-Type:.*soap" /var/log/apache2/access.log | \
awk '$9>=500 {print}' # codes 500+ = erreurs serveur potentielles
Logs base de données (Firebird)
- Requêtes contenant des séquences inhabituelles ou des erreurs de syntaxe SQL répétées depuis la même source
- Tentatives d'union, sous-requêtes, ou tokens SQL après des chaînes apparemment fermées
Mitigation et patch
Action immédiate
# Debian/Ubuntu
sudo apt update && sudo apt install php8.3=8.3.31-* php8.3-cli php8.3-fpm
# RHEL/Alma/Rocky (via Remi)
sudo dnf module install php:remi-8.3
sudo dnf update php php-cli php-fpm php-soap
# Composer (image Docker)
docker pull php:8.3-fpm-alpine # tire la dernière release patchée
docker compose up -d
Workaround si patch impossible immédiatement
Pour SOAP : désactivez l'extension si vous ne l'utilisez pas, ou bloquez les requêtes SOAP au niveau WAF :
; php.ini
; commenter pour désactiver
;extension=soap
# Nginx — bloquer les endpoints SOAP non utilisés
location ~ \.wsdl$ {
return 403;
}
Pour PDO Firebird : migrez les requêtes critiques vers des prepared statements, et filtrez les NUL bytes en entrée :
$input = str_replace("\0", '', $input);
Hardening durable
- Migrer toutes les requêtes SQL vers des prepared statements (élimine 99% des SQLi)
- Auditer l'utilisation de SOAP : si possible, migrer vers REST/GraphQL (SOAP est obsolescent)
- Mettre en place un monitoring automatique des versions PHP sur votre parc
Pourquoi surveiller en continu vos runtimes applicatifs
PHP est embarqué dans des dizaines de milliers de sites en production : un correctif publié n'a aucun impact tant qu'il n'est pas déployé. L'expérience montre que les versions PHP traînent souvent 6 à 12 mois derrière les dernières mises à jour de sécurité dans les inventaires moyens. Une CVE comme CVE-2026-6722 (RCE SOAP) peut être exploitée massivement avant que la majorité du parc soit patchée.
Avec cveo.tech, inventoriez vos runtimes (PHP, Node.js, Python, Ruby, Java) et soyez alerté automatiquement dès qu'une CVE critique vise une de vos versions exactes — pour planifier le patch avant que les exploits publics n'apparaissent.