This is a forged backstage pass, not a front-door battering ram
Tenable plugin 165545 flags PHP 7.4.x < 7.4.32 for two issues: CVE-2022-31629, where PHP can mangle crafted cookie names so an insecure cookie is treated like __Host- or __Secure-; and CVE-2022-31628, where PHAR/gzip handling can spin into an infinite loop on a malicious quine archive. Tenable keys off the installed PHP version, while the upstream CVE records describe the affected lines as PHP before 7.4.31 / 8.0.24 / 8.1.11; the practical upstream security release for 7.4 users was 7.4.32, which is what the plugin expects.
This should not be treated like a generic internet-facing PHP RCE. The vendor-style score is inflated if you read only the integrity impact on paper: CVE-2022-31629 needs a same-site sibling-domain foothold or on-path network position *and* an app that actually trusts __Host-/__Secure- cookie semantics for security decisions; CVE-2022-31628 is mostly an app-assisted DoS path around attacker-controlled PHAR/gzip input. For a fleet view, that lands in MEDIUM: worth fixing, but not a drop-everything event.
4 steps from start to impact.
Get a same-site or on-path foothold
CVE-2022-31629 is not the PHP host itself; it is attacker control of a sibling subdomain, weak internal HTTP, or a network MITM position. Tooling is mundane: subdomain takeover playbooks, mitmproxy, or any browser-capable phishing/lure flow. This prerequisite already implies the attacker has another foothold or your domain hygiene is weak.- Victim browses to an attacker-controlled sibling domain or over an attacker-observable/modifiable network path
- Cookies for the parent domain can be set or influenced
- Target application is PHP-based
- No value if the attacker cannot influence cookies for the target origin tree
- Strong HSTS and clean sibling-domain hygiene reduce the reachable population sharply
- This is not unauthenticated direct-to-service exploitation
Plant a forged cookie name
..Host-xsrf so PHP's historical name mangling converts it into __Host-xsrf in $_COOKIE. The bug report demonstrates the exact pattern and a CSRF bypass scenario. Tooling can be as simple as a browser response header, curl, or mitmproxy injecting Set-Cookie.- Browser accepts the attacker-set cookie
- Target app later receives the cookie on a request to the protected PHP origin
- Only works where browser/domain/path rules line up
- Apps that do not use
__Host-or__Secure-cookies for trust decisions get little or no security impact - Modern browsers still enforce their own cookie-prefix rules; the confusion happens in PHP parsing
Hit integrity-sensitive app logic
- Application reads the mangled cookie name from
$_COOKIE - That cookie participates in security logic, not just preferences or analytics
- Victim completes a request path that consumes the cookie
- A lot of PHP apps never rely on these cookie prefixes this way
- Additional app-layer protections like per-request CSRF state or server-side session binding may still stop abuse
- User interaction is required
Alternate sidecar path: PHAR gzip DoS
CVE-2022-31628 is the weaker companion issue. The reporter showed a crafted gzip/PHAR plus a simple PHP file operation can force infinite looping; weaponization used a tiny requests loop repeatedly hitting a vulnerable endpoint. In enterprise reality this is mostly relevant where untrusted archive input reaches PHAR-aware functions or PharData.- Attacker can get a malicious gzip/PHAR into a place the app will touch
- Application uses PHAR wrappers or
PharDataon attacker-controlled content
- This is highly app-specific and often requires upload or file-placement capability first
- No confidentiality or integrity gain; impact is mainly worker exhaustion/DoS
- EPSS is tiny and CISA ADP marks exploitation as none
165545 does not test exploitability; it trusts the self-reported version only.The supporting signals.
| Dominant risk in the bundle | CVE-2022-31629 drives this finding. CVE-2022-31628 is the weaker sidecar and mostly a constrained DoS path. |
|---|---|
| In-the-wild status | No KEV listing found, and CISA ADP SSVC on both CVEs says Exploitation: none. |
| Public PoC status | Yes, but mostly *report-grade* PoCs: bug #81727 includes a worked cookie-confusion/CSRF example; bug #81726 includes exploit.py and a test case for the PHAR/gzip loop. |
| EPSS | CVE-2022-31629: 15.416% EPSS, 94.761 percentile. CVE-2022-31628: 0.014% EPSS, 2.676 percentile. That split is the real story: one is plausible abuse, the other is background noise. |
| KEV status and dates | Not present in CISA KEV as checked against the current catalog mirror; public disclosure landed on 2022-09-27/2022-09-28 depending on source record. |
| CVSS vector reality check | CVE-2022-31629 is CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:N (6.5). The UI:R matters: this is not a fire-and-forget internet smash. CVE-2022-31628 has a much lower CNA score and is effectively DoS-only. |
| Affected versions | Upstream records call out PHP before 7.4.31, 8.0.24, and 8.1.11; Tenable plugin 165545 uses 7.4.x < 7.4.32 because 7.4.32 is the practical upstream 7.4 security release it keys on. |
| Fixed versions and backports | Upstream fix line for 7.4 is 7.4.32. Distro backports exist; for example Ubuntu 20.04 LTS fixed PHP 7.4 in package 7.4.3-4ubuntu2.15. |
| Scanner and exposure caveat | Tenable explicitly says the plugin did not test the flaws and relied on the application's self-reported version. Raw PHP banner exposure is therefore a bad proxy for exploitability. |
| Researchers | CVE-2022-31629 was reported by squarcina. CVE-2022-31628 credits ohseungju5 with reporter credit to @real_as3617 and @gPayl0ad. |
noisgate verdict.
The decisive friction is attacker position: the meaningful bug here needs a same-site sibling-domain foothold or on-path network influence, not a direct unauthenticated shot at the PHP service. That sharply narrows the exposed population and turns this into an application-trust problem, not a broad PHP platform compromise.
Why this verdict
- Start from the real baseline: the strongest CVE in the bundle is
CVE-2022-31629at6.5/MEDIUM, not a critical PHP runtime bug. - Downshift for attacker position: exploitation usually requires a same-site sibling domain or on-path network control, which implies prior foothold, domain hygiene failure, or internal-network advantage rather than raw internet reach.
- Downshift for app dependence: impact only materializes when the target PHP application uses
__Host-/__Secure-cookies in integrity-sensitive logic such as CSRF or trust binding; many deployments do not. - Keep it at MEDIUM, not LOW: PHP is ubiquitous, the bug is silent when it works, and
CVE-2022-31629has a nontrivial EPSS signal, so this is more than backlog lint. - Ignore the sidecar inflation:
CVE-2022-31628is mostly an app-assisted DoS route around attacker-controlled PHAR/gzip handling and should not pull the bundle upward.
Why not higher?
There is no pre-auth RCE, no broad data-exfil path, no KEV evidence, and no one-packet internet exploit. The highest-impact path depends on browser interaction plus specific app trust decisions, so the blast radius is much narrower than the product footprint suggests.
Why not lower?
This is still a security-control bypass in a very common runtime, not just a cosmetic parser quirk. If you have shadow subdomains, mixed HTTP/HTTPS inside the same parent domain, or legacy CSRF patterns tied to prefixed cookies, the bug can be operationally relevant.
What to do — in priority order.
- Audit sibling-domain trust — Inventory dangling, parked, and legacy subdomains under the same parent domain, then remove or lock them down. This cuts off the most realistic
CVE-2022-31629attacker position; for a MEDIUM verdict there is no mitigation SLA — go straight to the 365-day remediation window, but do this sooner on internet-facing estates because it reduces more than one class of web risk. - Enforce HTTPS and HSTS consistently — Remove plain-HTTP footholds that let on-path or downgrade-style cookie planting happen on sibling properties. This is a structural defense, not a full fix, and for MEDIUM there is no mitigation SLA — go straight to the 365-day remediation window.
- Review cookie-trust patterns in PHP apps — Identify applications that treat
__Host-or__Secure-cookies as integrity anchors for CSRF, request validation, or session security. Where found, revalidate those assumptions and pair with server-side checks while you remediate within the 365-day window. - Constrain PHAR handling of untrusted input — For upload-heavy apps, review any use of
phar://,PharData, or archive inspection against user-controlled files. This specifically narrows the DoS sidecarCVE-2022-31628; again, MEDIUM means no mitigation SLA — go straight to the 365-day remediation window.
- A generic WAF does not reliably fix cookie-name confusion once the browser legally stores and forwards the cookie; the app receives a normal request.
- Hiding PHP version banners does not remove the bug and only makes version-only scanners less noisy.
- Treating
CVE-2022-31628as the main driver is a prioritization mistake; it does not justify emergency runtime patching by itself.
Crowdsourced verification payload.
Run this on the target Linux host that actually serves PHP, not on the scanner. Save it as check_php_165545.sh and run sudo bash check_php_165545.sh; root is helpful for package metadata access but usually not strictly required. The script checks upstream PHP 7.4.32 and common Debian/Ubuntu backports, then prints VULNERABLE, PATCHED, or UNKNOWN.
#!/usr/bin/env bash
# check_php_165545.sh
# Verify exposure for Nessus plugin 165545 / PHP 7.4.x < 7.4.32
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
set -u
FIXED_UPSTREAM="7.4.32"
FIXED_UBUNTU_FOCAL="7.4.3-4ubuntu2.15"
FIXED_DEBIAN_BULLSEYE="7.4.33-1+deb11u1"
print_result() {
local status="$1"
local msg="$2"
echo "$status: $msg"
case "$status" in
PATCHED) exit 0 ;;
VULNERABLE) exit 1 ;;
*) exit 2 ;;
esac
}
ver_ge() {
# semantic-ish compare for upstream versions
[ "$(printf '%s\n' "$1" "$2" | sort -V | tail -n1)" = "$1" ]
}
php_ver=""
if command -v php >/dev/null 2>&1; then
php_ver="$(php -r 'echo PHP_VERSION;' 2>/dev/null || true)"
fi
os_id=""
os_ver=""
if [ -r /etc/os-release ]; then
. /etc/os-release
os_id="${ID:-}"
os_ver="${VERSION_ID:-}"
fi
# Debian/Ubuntu package-aware checks first because distro backports matter.
if command -v dpkg-query >/dev/null 2>&1; then
pkg_ver=""
for p in php7.4-cli php7.4-fpm libapache2-mod-php7.4 php7.4-common php7.4; do
if dpkg-query -W -f='${Version}\n' "$p" >/dev/null 2>&1; then
pkg_ver="$(dpkg-query -W -f='${Version}\n' "$p" 2>/dev/null | head -n1)"
[ -n "$pkg_ver" ] && break
fi
done
if [ -n "$pkg_ver" ]; then
if [ "$os_id" = "ubuntu" ] && [ "$os_ver" = "20.04" ]; then
if dpkg --compare-versions "$pkg_ver" ge "$FIXED_UBUNTU_FOCAL"; then
print_result PATCHED "Ubuntu 20.04 package version $pkg_ver includes the fix line for CVE-2022-31628/CVE-2022-31629."
else
print_result VULNERABLE "Ubuntu 20.04 package version $pkg_ver is older than fixed backport $FIXED_UBUNTU_FOCAL."
fi
fi
if [ "$os_id" = "debian" ] && [ "$os_ver" = "11" ]; then
if dpkg --compare-versions "$pkg_ver" ge "$FIXED_DEBIAN_BULLSEYE"; then
print_result PATCHED "Debian 11 package version $pkg_ver includes the DSA-5277 fix line."
else
print_result VULNERABLE "Debian 11 package version $pkg_ver is older than fixed backport $FIXED_DEBIAN_BULLSEYE."
fi
fi
# Fallback for other dpkg-based systems: use the runtime version if available.
if [ -n "$php_ver" ]; then
case "$php_ver" in
7.4.*)
if ver_ge "$php_ver" "$FIXED_UPSTREAM"; then
print_result PATCHED "Runtime reports PHP $php_ver (>= $FIXED_UPSTREAM)."
else
print_result VULNERABLE "Runtime reports PHP $php_ver (< $FIXED_UPSTREAM) and no recognized backport rule matched."
fi
;;
8.*|9.*)
print_result PATCHED "Runtime reports PHP $php_ver; plugin 165545 targets 7.4.x only."
;;
esac
fi
fi
fi
# RPM-based best-effort: changelog hit is stronger than raw version because of backports.
if command -v rpm >/dev/null 2>&1; then
for p in php php-cli php-fpm php-common; do
if rpm -q "$p" >/dev/null 2>&1; then
if rpm -q --changelog "$p" 2>/dev/null | grep -Eq 'CVE-2022-31628|CVE-2022-31629|RHSA-2023:2903|ALSA-2023:2903|ELSA-2023:0848'; then
print_result PATCHED "RPM package $p changelog shows a backport/fix reference for CVE-2022-31628/CVE-2022-31629."
fi
fi
done
fi
# Pure upstream/source-build check.
if [ -n "$php_ver" ]; then
case "$php_ver" in
7.4.*)
if ver_ge "$php_ver" "$FIXED_UPSTREAM"; then
print_result PATCHED "Runtime reports upstream PHP $php_ver (>= $FIXED_UPSTREAM)."
else
print_result VULNERABLE "Runtime reports upstream PHP $php_ver (< $FIXED_UPSTREAM)."
fi
;;
8.*|9.*)
print_result PATCHED "Runtime reports PHP $php_ver; this specific finding is for PHP 7.4.x."
;;
*)
print_result UNKNOWN "PHP runtime found ($php_ver), but this script only classifies PHP 7.4.x precisely for plugin 165545."
;;
esac
fi
print_result UNKNOWN "Could not determine a PHP 7.4 runtime or package state with enough confidence. Check package manager metadata and distro advisories manually."If you remember one thing.
165545 like an emergency fleet-wide PHP compromise. First, separate true upstream/source builds from distro-backported packages, because the plugin is version-driven and explicitly version-only. For this MEDIUM reassessment there is no noisgate mitigation SLA — go straight to the 365-day remediation window; your noisgate remediation SLA is ≤365 days. In practice, validate internet-facing PHP 7.4 hosts this week, identify apps that trust __Host-/__Secure- cookies, and fold any still-exposed 7.4 systems into your PHP retirement plan this quarter because 7.4 itself is long out of support.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.