On May 10, 2026, the PHP team released simultaneous fixes for three CRITICAL vulnerabilities (CVSS 9.8) affecting every PHP 8.2.x, 8.3.x, 8.4.x and 8.5.x branch. Two hit the SOAP extension (use-after-free leading to memory corruption and potentially RCE), one hits the PDO Firebird driver (SQL injection via NUL byte). Given PHP's ubiquity across the web ecosystem (WordPress, Drupal, Magento, Laravel, Symfony…), this is a top-priority update.
Patched versions: 8.2.31, 8.3.31, 8.4.21, 8.5.6.
Overview
| CVE | Component | Type | CVSS | Exploitation conditions |
|---|---|---|---|---|
| CVE-2025-14179 | PDO Firebird driver | SQL injection (NUL byte) | 9.8 | Use of PDO::quote() with attacker-controlled values |
| CVE-2026-6722 | SOAP — object dedup | Use-after-free → RCE | 9.8 | SoapServer receiving SOAP requests with duplicated apache:Map keys |
| CVE-2026-7261 | SOAP — session persistence | Use-after-free | 9.8 | SoapServer configured with SOAP_PERSISTENCE_SESSION |
CVE-2025-14179 — PDO Firebird: NUL byte breaks PDO::quote()
The bug
When PHP's Firebird PDO driver constructs a query token by token, a string token containing a NUL byte (\0) is copied via strncat(). But strncat() stops at the first NUL — the copy truncates the string, the closing quote is never written, and subsequent SQL tokens are interpreted as part of the open string.
Concretely, this turns:
SELECT * FROM users WHERE name = 'attacker\0' AND role = 'admin'
into:
SELECT * FROM users WHERE name = 'attacker' AND role = 'admin
↑
string left open
→ injection possible
Any attacker-controlled value passed to PDO::quote() before embedding into a SQL query opens up classic SQL injection.
Exploitation conditions
- PHP application using the PDO Firebird driver (Firebird/Interbase databases)
- Use of
PDO::quote()instead of parameterized prepared statements - Attacker ability to inject a NUL byte in the value (often possible via certain encodings, custom HTTP headers, or binary fields)
Immediate mitigation
Beyond the patch, migrate to prepared statements:
// VULNERABLE
$query = "SELECT * FROM users WHERE name = " . $pdo->quote($input);
$pdo->query($query);
// SAFE — prepared statement
$stmt = $pdo->prepare("SELECT * FROM users WHERE name = ?");
$stmt->execute([$input]);
This is the correct, durable mitigation, independent of this CVE.
CVE-2026-6722 — SOAP: use-after-free via duplicated-key object dedup
The bug
PHP's SOAP extension uses an object deduplication mechanism: while parsing a SOAP request, pointers to PHP objects are stored in a global map without incrementing their reference counts.
When an apache:Map node contains duplicate keys, processing the second entry overwrites the first in the temporary result map, freeing the original PHP object while its stale pointer remains in the map. A subsequent href reference to the freed node copies the dangling pointer into the result.
From UAF to RCE
PHP string allocations can reuse the freed memory region. An attacker controlling the SOAP request body can therefore:
- Force the object to be freed (via duplicate keys)
- Allocate a PHP string of the right size to occupy the region
- Place a forged object there (class pointer pointing to a malicious vtable)
- Trigger a method call on the dangling pointer → RCE
Typical vector: AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H (no auth, network exploit).
Exploitation conditions
- PHP SoapServer exposed over HTTP/HTTPS
- Acceptance of SOAP requests with attacker-controlled bodies (the standard case)
- No authentication or user interaction required
CVE-2026-7261 — SOAP: use-after-free on SOAP_PERSISTENCE_SESSION
The bug
When SoapServer is configured with SOAP_PERSISTENCE_SESSION, the handler object is persisted across requests via session storage. If a SOAP request generates an error, the persistence path is mishandled: the object is freed while keeping a pointer to it in the session.
A subsequent request from the same client reuses the dangling pointer, leading to:
- Memory corruption
- Information disclosure
- PHP process crash
Depending on the allocator, exploitation can escalate to RCE similar to CVE-2026-6722, though less automatic.
Exploitation conditions
- SoapServer configured with
SOAP_PERSISTENCE_SESSION(common for stateful SOAP APIs) - Attacker ability to trigger an error on one request, then send a second request
Affected Products and Versions
| PHP branch | Affected versions | Patched version |
|---|---|---|
| 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 and earlier are end-of-support and receive no official fix — any deployment on these versions is permanently vulnerable.
Check your version
# Local
php -v
# On a server
ssh server "php -v"
# In a Docker container
docker exec my-app php -v
# Loaded modules (check whether SOAP and PDO Firebird are active)
php -m | grep -E "soap|pdo_firebird"
Detection and IOCs
PHP logs
Watch /var/log/php/error.log (or equivalent):
- SoapFault errors or warnings in
SoapServer::handle - PHP-FPM process crashes (segfaults visible in
dmesgor systemd logs) - "Dereferenced" PHP object entries in stack traces
Web server logs
# Suspicious SOAP requests (apache:Map with repeated keys)
grep -E "POST.*\.wsdl|Content-Type:.*soap" /var/log/apache2/access.log | \
awk '$9>=500 {print}' # 500+ codes = potential server errors
Database logs (Firebird)
- Queries containing unusual sequences or repeated SQL syntax errors from the same source
- Attempts at UNIONs, subqueries, or SQL tokens after apparently-closed strings
Mitigation and Patch
Immediate action
# 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 (Docker image)
docker pull php:8.3-fpm-alpine # pulls the latest patched release
docker compose up -d
Workaround if patching is delayed
For SOAP: disable the extension if unused, or block SOAP requests at the WAF:
; php.ini
; comment to disable
;extension=soap
# Nginx — block unused SOAP endpoints
location ~ \.wsdl$ {
return 403;
}
For PDO Firebird: migrate critical queries to prepared statements, and strip NUL bytes in input:
$input = str_replace("\0", '', $input);
Long-term hardening
- Migrate all SQL queries to prepared statements (eliminates 99% of SQLi)
- Audit SOAP usage: if possible, migrate to REST/GraphQL (SOAP is legacy)
- Set up automated PHP version monitoring across your fleet
Why Continuous Monitoring of Application Runtimes Matters
PHP is embedded in tens of thousands of production sites: a released patch has zero impact until it's deployed. Experience shows PHP versions often lag 6 to 12 months behind the latest security updates in average inventories. A CVE like CVE-2026-6722 (SOAP RCE) can be exploited at scale before most of the fleet is patched.
With cveo.tech, inventory your application runtimes (PHP, Node.js, Python, Ruby, Java) and get automatic alerts when a critical CVE targets one of your exact versions — so you can plan the patch before public exploits appear.