This is less a front-door master key and more a brittle latch that only fails on one oddly wired side entrance
CVE-2026-7261 is a SoapServer use-after-free in PHP when an application uses SOAP_PERSISTENCE_SESSION, which stores the handler object in session state across requests. The bug is hit on an error path: if a SOAP header handler throws or returns failure, PHP frees the handler object but later still reuses it during session writeback. Affected upstream branches are PHP 8.2.0-8.2.30, 8.3.0-8.3.30, 8.4.0-8.4.20, and 8.5.0-8.5.5; fixed versions are 8.2.31, 8.3.31, 8.4.21, and 8.5.6.
The vendor-side reality is already telling you this is not a generic critical. PHP's own advisory scores it Moderate with CVSS v4 6.3, while NVD's CVSS v3.1 auto-style scoring shows 9.8 because it models the bug as a raw network-reachable memory safety issue and ignores the deployment friction. In real estates, the attacker needs a reachable SOAP endpoint, the app must specifically use SoapServer::setClass() with SOAP_PERSISTENCE_SESSION, and the exploit path depends on an error-producing header handler plus difficult heap control; that combination is why this lands in MEDIUM, not CRITICAL.
5 steps from start to impact.
Find a live PHP SOAP server
curl, Burp Suite, or a custom HTTP client. This is not 'all PHP on the internet'; it is only applications that actually expose ext-soap server functionality.- A SOAP endpoint is network reachable
- The endpoint is backed by PHP
SoapServerrather than some other stack
- SOAP is now a minority pattern in many enterprises
- Most internet scanning can identify PHP broadly but not confirm
SoapServerusage
/wsdl or SOAP-style POST behavior, but commodity vuln scanners have weak direct coverage for this specific code path.Hit the narrow vulnerable configuration
SoapServer::setClass() and enable SOAP_PERSISTENCE_SESSION, which serializes the handler object into session storage between requests, per the PHP manual. Without that exact persistence mode, this CVE does not fire.- Application uses
SOAP_PERSISTENCE_SESSION - PHP
ext-soapis installed and active - The vulnerable branch/version is deployed
- This flag is uncommon and app-specific
- You cannot infer this setting from a banner or package scan alone
- Many SOAP implementations use request-scoped handlers instead
SOAP_PERSISTENCE_SESSION.Trigger the header-fault error path
- The endpoint accepts attacker-controlled SOAP input
- A header handler exists and can be induced to throw or fail
- Malformed XML alone is not enough; the attacker needs the right application behavior
- Many SOAP services do little or no custom header handling
php-fpm logs.Reuse the session and touch the dangling object
- Attacker can maintain or replay the same session
- The allocator state is favorable enough for useful reuse of freed memory
- Heap shaping is hard in this path
- A single-request execution model reduces attacker control
- Modern hardening often turns memory bugs into crashes instead of RCE
php-fpm child respawns, and crash-looping around SOAP requests.Turn corruption into meaningful impact
- Advanced exploit development time
- Target-specific reliability testing
- No public weaponized exploit found
- No KEV listing or active exploitation evidence found
- The path is too narrow for spray-and-pray internet exploitation
The supporting signals.
| In-the-wild status | No authoritative exploitation evidence found in the sourced material. CISA KEV: not listed. |
|---|---|
| Proof-of-concept availability | A vendor-authored reproducer exists in the GitHub advisory (GHSA-m33r-qmcv-p97q), but I found no public weaponized exploit repo or repeatable RCE chain. |
| EPSS | User-supplied EPSS is 0.0007; third-party mirrors around publication also show roughly 0.00059%-0.06% probability and an extremely low percentile. Read that as 'little market interest,' not zero risk. |
| KEV status | No. Not present in the CISA Known Exploited Vulnerabilities catalog. |
| CVSS discrepancy | NVD lists CVSS v3.1 9.8 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H), but the PHP CNA advisory uses CVSS v4 6.3 with AT:P, which better reflects the extra deployment prerequisite. |
| Affected versions | Upstream affected: 8.2.0-8.2.30, 8.3.0-8.3.30, 8.4.0-8.4.20, 8.5.0-8.5.5. |
| Fixed versions | Upstream fixed: 8.2.31, 8.3.31, 8.4.21, 8.5.6. Distro examples: Debian php8.2 8.2.31-1~deb12u1, Debian php8.4 8.4.21-1~deb13u1, Amazon Linux 2 php8.2 fixed in ALAS2PHP8.2-2026-011. |
| Exposure/scanning reality | There is no reliable internet census for SOAP_PERSISTENCE_SESSION usage. Shodan/Censys can help find public PHP or SOAP endpoints, but they cannot prove this specific runtime flag from the outside. |
| Disclosure timeline | PHP released fixes on 2026-05-07; NVD/CVE publication shows 2026-05-10. |
| Reporter / source | Source/CNA is PHP Group; advisory published in php/php-src GitHub Security Advisories. |
noisgate verdict.
The decisive factor is the configuration bottleneck: this bug matters only when a reachable PHP SOAP service is using SOAP_PERSISTENCE_SESSION, an uncommon and externally non-obvious deployment choice. That sharply reduces exposed population and makes the NVD-style 9.8 internet-RCE framing too aggressive for enterprise prioritization.
Why this verdict
- Baseline down from 9.8: the raw memory-corruption class is scary, but the PHP CNA itself scores this
6.3because exploitation needs extra attack requirements, not just a socket. - Population is narrow: the attacker needs a public or reachable SOAP service using PHP
ext-soap,SoapServer::setClass(), and specificallySOAP_PERSISTENCE_SESSION; each prerequisite compounds downward pressure. - Impact is not cleanly reliable: the advisory says SOAP usually handles one request per PHP request, so controlling the freed chunk is unlikely; in many real deployments the plausible outcome is crash or unstable worker behavior before dependable RCE.
Why not higher?
I am not taking this to HIGH or CRITICAL because it is not a universal pre-auth path against generic PHP. The attack requires a rare application pattern and a brittle error path, and there is no KEV entry, no sourced in-the-wild exploitation evidence, and no public weaponized exploit chain showing reliable code execution.
Why not lower?
I am not dropping this to LOW because the bug is still remotely triggerable with no authentication if the vulnerable app pattern exists. It sits in a server-side memory-safety path, so a reachable affected SOAP service can still suffer process crashes or possibly information disclosure, which is more than backlog-only hygiene.
What to do — in priority order.
- Inventory PHP SOAP servers — Identify hosts exposing SOAP endpoints and confirm whether application code calls
setPersistence(SOAP_PERSISTENCE_SESSION). For a MEDIUM verdict there is no noisgate mitigation SLA, so use this as immediate scoping work and go straight toward the 365-day remediation window. - Disable session persistence where feasible — If the application can tolerate it, remove
SOAP_PERSISTENCE_SESSIONor switch to request-scoped handling to kill the vulnerable path without waiting for a full stack uplift. There is no mitigation SLA for MEDIUM, but this is the cleanest interim risk reduction if you discover internet-facing SOAP services. - Restrict exposure to legacy SOAP endpoints — Put externally reachable SOAP services behind VPN, reverse-proxy allowlists, or strong application auth where business permits. Again, MEDIUM carries no mitigation SLA, but narrowing reachability materially cuts risk while you schedule the actual PHP upgrade inside the remediation window.
- Monitor for SOAP fault crashes — Alert on
php-fpmworker respawns, segfaults, core dumps, and bursts of SOAP faults from the same client/session. This does not remove the bug, but it raises the odds you catch probing or unreliable exploit development before it becomes an outage.
- Hiding PHP version banners does not help; the attacker's real problem is endpoint discovery and app behavior, not just banner parsing.
- Composer/SCA-only dependency scanning does not reliably catch this because
ext-soapis a built-in/runtime component, not just an application package incomposer.lock. - A generic WAF rule for malformed XML does not guarantee coverage; the vulnerable path depends on valid-enough SOAP requests that trigger application header-handler failure.
Crowdsourced verification payload.
Run this on the target PHP application host. Save it as check-cve-2026-7261.sh and run bash check-cve-2026-7261.sh /var/www to also inspect deployed code for SOAP_PERSISTENCE_SESSION; no root is required unless the PHP binary or app tree is restricted.
#!/usr/bin/env bash
# check-cve-2026-7261.sh
# Detect likely exposure to CVE-2026-7261 on a host.
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
set -u
APP_PATH="${1:-}"
PHP_BIN="${PHP_BIN:-php}"
ver_lt() {
# returns 0 if $1 < $2
[ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)" != "$2" ] && return 1
[ "$1" = "$2" ] && return 1
return 0
}
in_vuln_range() {
local v="$1"
if ver_lt "$v" "8.2.31" && ! ver_lt "$v" "8.2.0"; then return 0; fi
if ver_lt "$v" "8.3.31" && ! ver_lt "$v" "8.3.0"; then return 0; fi
if ver_lt "$v" "8.4.21" && ! ver_lt "$v" "8.4.0"; then return 0; fi
if ver_lt "$v" "8.5.6" && ! ver_lt "$v" "8.5.0"; then return 0; fi
return 1
}
if ! command -v "$PHP_BIN" >/dev/null 2>&1; then
echo "UNKNOWN: php binary not found in PATH"
exit 2
fi
PHP_VERSION="$($PHP_BIN -r 'echo PHP_VERSION;' 2>/dev/null)"
if [ -z "$PHP_VERSION" ]; then
echo "UNKNOWN: unable to determine PHP version"
exit 2
fi
SOAP_LOADED="$($PHP_BIN -m 2>/dev/null | awk 'BEGIN{IGNORECASE=1} /^soap$/{print "yes"}')"
if [ "$SOAP_LOADED" != "yes" ]; then
echo "UNKNOWN: ext-soap not loaded in this PHP SAPI; verify web SAPI separately"
exit 2
fi
if ! in_vuln_range "$PHP_VERSION"; then
echo "PATCHED: PHP $PHP_VERSION is outside the affected upstream ranges"
exit 0
fi
if [ -z "$APP_PATH" ]; then
echo "UNKNOWN: PHP $PHP_VERSION is in an affected range and ext-soap is loaded; rerun with app path to check for SOAP_PERSISTENCE_SESSION usage"
exit 2
fi
if [ ! -d "$APP_PATH" ]; then
echo "UNKNOWN: app path '$APP_PATH' does not exist or is not a directory"
exit 2
fi
MATCHES=$(grep -RInE 'SOAP_PERSISTENCE_SESSION|setPersistence\s*\(\s*1\s*\)' "$APP_PATH" 2>/dev/null | head -n 20 || true)
if [ -n "$MATCHES" ]; then
echo "VULNERABLE: PHP $PHP_VERSION is affected, ext-soap is loaded, and app code appears to use SOAP_PERSISTENCE_SESSION"
echo "$MATCHES"
exit 1
fi
echo "UNKNOWN: PHP $PHP_VERSION is affected and ext-soap is loaded, but no obvious SOAP_PERSISTENCE_SESSION usage was found under $APP_PATH"
exit 2
If you remember one thing.
9.8 exists in one scoring view. First identify any internet-facing or partner-facing PHP SOAP services and confirm whether they use SOAP_PERSISTENCE_SESSION; if they do, disable that mode or restrict exposure as best-effort hardening. For a MEDIUM verdict there is no noisgate mitigation SLA — go straight to the 365-day remediation window; apply the vendor fix or distro backport within the noisgate remediation SLA of 365 days, but pull confirmed exposed session-persisted SOAP servers forward into your next normal web-stack maintenance cycle rather than leaving them to year-end drift.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.