← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
tenable:161971 · CWE-120 · Disclosed 2022-06-16

PHP 7

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

This is less an unlocked front door than a bad hinge on a door most attackers can’t even reach

Tenable plugin 161971 rolls up two PHP flaws fixed in 7.4.30: CVE-2022-31625 in the PostgreSQL extension and CVE-2022-31626 in pdo_mysql with the mysqlnd driver. Affected upstream ranges are PHP 7.4.0-7.4.29, plus parallel 8.0/8.1 ranges. The first bug needs attacker-controlled input to code paths using pg_query_params(). The second needs an application pattern where an untrusted party can influence the MySQL host and password, often by pointing PHP at a rogue MySQL server and sending an abnormally long password.

The vendor/NVD story overstates fleet-wide urgency if you manage thousands of ordinary PHP web nodes. Yes, the technical impact can be RCE, and public exploit material exists. But this is not a broad unauthenticated internet-to-RCE bug against 'any PHP site'; it is extension-specific, workflow-specific, and often requires an already-dangerous app design such as self-service DB connection forms or admin tools like Adminer/phpMyAdmin. That friction pulls this down from HIGH to a solid MEDIUM for most enterprises.

"Real bug, real RCE potential, but the exploit path is narrow and highly app-dependent."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Find a reachable PHP 7.4.29-or-older target

The attacker first needs a host actually running upstream-vulnerable PHP < 7.4.30. Tenable itself notes this plugin is version-only and relies on the application's self-reported version, so scanner hits will include systems where the risky extensions or workflows are absent. Weaponized tools at this stage are routine fingerprinting and version enumeration, not a vulnerability-specific exploit.
Conditions required:
  • PHP 7.4.x earlier than 7.4.30 is deployed
  • Version is externally observable or discoverable by authenticated scanning
Where this breaks in practice:
  • PHP version disclosure is often suppressed
  • A remote version hit does not prove pdo_mysql/mysqlnd or pgsql is loaded
  • Distro-packaged builds may be backported differently than simple banner logic implies
Detection/coverage: Good scanner coverage for version exposure; poor coverage for whether the dangerous code path is actually reachable.
STEP 02

Reach the specific vulnerable workflow

For CVE-2022-31626, the attacker needs an application that lets an untrusted user influence the DB host and credentials so PHP will connect to an attacker-controlled MySQL endpoint; Ambionics explicitly called out tools such as Adminer and phpMyAdmin. For CVE-2022-31625, the target app must pass attacker-controlled values into PostgreSQL parameterized-query handling in a way that triggers the bad free path. The weaponized tooling here is a rogue MySQL server or crafted app input, not a generic web exploit kit.
Conditions required:
  • pdo_mysql with mysqlnd is installed for 31626, or PostgreSQL extension usage for 31625
  • Application exposes user influence over DB connection parameters or query parameter types
  • Attacker can reach the admin/self-service workflow
Where this breaks in practice:
  • Most production PHP apps never let internet users choose the DB host/password
  • Many enterprises do not expose DB admin consoles publicly
  • The PostgreSQL bug depends on a narrower coding pattern than ordinary form submission
Detection/coverage: Scanners generally miss this prerequisite. You need app inventory, extension inventory, and route mapping.
STEP 03

Trigger memory corruption

The exploit fires when PHP processes the malformed input in the vulnerable extension. For CVE-2022-31626, Ambionics showed a fake MySQL server plus an excessively long password can trigger the overflow; for CVE-2022-31625, invalid parameter handling in pg_query_params() can lead to freeing uninitialized pointers. This is where the issue becomes technically serious, but only after the earlier setup hurdles are cleared.
Conditions required:
  • Attacker can drive the exact extension code path
  • Input shape matches the vulnerable edge case
  • PHP worker process reaches the relevant function
Where this breaks in practice:
  • Long-password edge cases are unusual in real traffic
  • Crashing a worker is easier than stable code execution
  • Modern hardening may reduce exploit reliability even when the bug is reachable
Detection/coverage: Network IDS/WAF coverage is weak; host-side crash telemetry, PHP-FPM/Apache worker faults, and abnormal outbound DB connection attempts are more useful.
STEP 04

Convert crash to code execution and pivot

If memory corruption is made reliable, the attacker lands code execution in the context of the PHP worker, then pivots into application secrets, local files, or adjacent services. In practice, many attempts will degrade into denial of service rather than deterministic RCE. The practical blast radius is therefore the web app tier, not automatic domain-wide compromise.
Conditions required:
  • Exploit reliability on the target build
  • Valuable secrets or lateral paths available from the PHP runtime context
Where this breaks in practice:
  • Exploit portability across builds is limited
  • Process isolation, containers, SELinux/AppArmor, and secret hygiene reduce payoff
  • No evidence this bug became a routine mass-exploitation internet spray target
Detection/coverage: EDR, container runtime telemetry, and anomalous child-process or outbound-connection alerts can catch post-exploitation better than perimeter controls.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusI found no current public evidence of KEV listing or broad active exploitation for CVE-2022-31625 / CVE-2022-31626. This is an inference from current public-source review, not proof of absence.
Public exploit / PoCYes. The PHP bug tracker entries are public and include exploit discussion; CVE-2022-31626 includes an Ambionics report with a fake MySQL server PoC and notes impact on tools such as Adminer/phpMyAdmin.
Reporting researcherCharles Fol, Ambionics reported both issues in May 2022.
EPSSCVE-2022-31626: about 12.89% / ~94th percentile; CVE-2022-31625: about 0.77% / ~73rd percentile according to current EPSS mirrors surfacing FIRST data.
KEV statusNot observed in CISA KEV public results during this review; no known KEV added date identified.
CVSS reality checkWorst-case score comes from CVE-2022-31626: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H at 8.8 HIGH from NVD, but the PHP CNA score is lower-complexity-adjusted at 7.5 HIGH because exploitation is conditional.
Affected versionsUpstream PHP affected: 7.4.0-7.4.29, 8.0.0-8.0.19, 8.1.0-8.1.6.
Fixed versionsUpstream fixed in 7.4.30, 8.0.20, and 8.1.7. Debian Bullseye fixed php7.4 in 7.4.30-1+deb11u1; Debian 10 LTS later carried fixes in 7.3.31-1~deb10u2; Gentoo marks unaffected >=7.4.30.
Exposure / scanningThird-party attack-surface telemetry on CVE Details shows roughly 304,589 IPs associated with affected exposure and port 80 as the top observed port, but treat that as coarse exposure data, not proof the dangerous extension path is reachable.
Disclosure timelinePHP 7.4.30 shipped on 2022-06-09; NVD published both CVEs on 2022-06-16.
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to MEDIUM (5.9/10)

The single biggest downward pressure is that exploitation usually requires a specific application design flaw or admin workflow, not just 'a PHP server on the internet.' This is a real memory-corruption issue with public exploit material, but reachability is narrow enough that most fleets should not treat every PHP 7.4 host as an urgent remote-RCE fire drill.

HIGH Affected-version and fix-version facts
MEDIUM Real-world exploitability for a generic enterprise PHP fleet
LOW Public internet exposure estimates tied to this exact code path

Why this verdict

  • Down from vendor HIGH: the worst bug (CVE-2022-31626) needs pdo_mysql with mysqlnd *and* an app flow where an attacker can influence DB host and password, which is uncommon in ordinary public web apps
  • More friction: CVE-2022-31625 requires PostgreSQL extension usage and a narrower bad-parameter path into pg_query_params(), so many PHP deployments are unaffected in practice even if the version is old
  • Still not LOW: public exploit material exists, the bugs can cross into real RCE territory, and exposed DB admin tooling or self-service connection workflows materially amplify risk

Why not higher?

This is not a broad unauthenticated internet exploit against vanilla PHP request handling. The attack path compounds multiple prerequisites: the right extension, the right application behavior, and often attacker influence over backend connection details or edge-case parameter types. That sharply narrows reachable population and keeps it out of HIGH for most 10,000-host environments.

Why not lower?

Calling it LOW would ignore two important facts: the impact can be full code execution in the PHP worker context, and exploit information is public enough to be operationalized against the small set of apps that expose the right workflow. If you run internet-reachable DB admin consoles or custom 'test connection' features, this can move from theoretical to very real.

05 · Compensating Control

What to do — in priority order.

  1. Map extension usage — Identify which hosts actually load pdo_mysql, mysqlnd, pgsql, or pdo_pgsql, and which apps expose DB connection testing or self-service login workflows. For a MEDIUM verdict there is no mitigation SLA — go straight to the 365-day remediation window, but do this discovery early so you can locally escalate the truly exposed subset.
  2. Restrict DB admin tools — Put Adminer, phpMyAdmin, phpPgAdmin, install wizards, and 'test DB connection' pages behind VPN, SSO, or strict source-IP allowlists. This cuts off the most plausible external path to CVE-2022-31626; for this MEDIUM case there is no mitigation SLA, but apply during normal hardening rather than waiting for the patch window to expire.
  3. Disable unused PHP extensions — If a host does not need PostgreSQL or pdo_mysql/mysqlnd, remove or disable those modules. That removes the vulnerable code path entirely and is often faster than waiting on app-owner patch cycles; again, no mitigation SLA — go straight to the 365-day remediation window for the software fix.
  4. Constrain outbound DB egress — Block web tiers from making arbitrary outbound MySQL/PostgreSQL connections except to approved database destinations. This is especially effective against the rogue-MySQL-server setup needed for CVE-2022-31626; apply as routine segmentation, not emergency response.
  5. Validate connection inputs — If you own custom code that accepts user-supplied DB connection values, cap password length and prohibit arbitrary host selection. That does not replace patching, but it directly addresses the exploit precondition the Ambionics report described.
What doesn't work
  • A generic WAF will not reliably stop this because the dangerous part may be a server-initiated connection to a rogue MySQL host or an app-internal extension path, not a recognizable HTTP payload alone.
  • Simply hiding the PHP version banner reduces reconnaissance noise but does nothing to remove the memory-corruption bug.
  • Patching only the database server does not help; the vulnerable code is in the PHP client-side extensions.
06 · Verification

Crowdsourced verification payload.

Run this on the target Linux/PHP host, not your scanner. Invoke it as bash check_php_7430.sh /usr/bin/php or just bash check_php_7430.sh if php is in PATH; root is not required, but the account must be able to execute the PHP CLI and read module/package metadata.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check_php_7430.sh
# Verify exposure to PHP 7.4.x < 7.4.30 issues covered by Tenable 161971
# Outputs one of: VULNERABLE / PATCHED / UNKNOWN
# Exit codes: 0 PATCHED, 1 VULNERABLE, 2 UNKNOWN

set -u

PHP_BIN="${1:-php}"

have_cmd() { command -v "$1" >/dev/null 2>&1; }
ver_ge() { [ "$(printf '%s\n' "$2" "$1" | sort -V | head -n1)" = "$2" ]; }
ver_lt() { [ "$1" != "$2" ] && [ "$(printf '%s\n' "$1" "$2" | sort -V | head -n1)" = "$1" ]; }

if ! have_cmd "$PHP_BIN"; then
  echo "UNKNOWN - php binary not found: $PHP_BIN"
  exit 2
fi

PHP_VER="$($PHP_BIN -r 'echo PHP_MAJOR_VERSION,".",PHP_MINOR_VERSION,".",PHP_RELEASE_VERSION;' 2>/dev/null)"
if [ -z "$PHP_VER" ]; then
  echo "UNKNOWN - unable to query PHP version"
  exit 2
fi

MODULES="$($PHP_BIN -m 2>/dev/null | tr '[:upper:]' '[:lower:]')"
PHPINFO_LINE="$($PHP_BIN -i 2>/dev/null | grep -i '^client api version => mysqlnd' | head -n1)"

has_pdo_mysql=0
has_mysqlnd=0
has_pgsql=0
has_pdo_pgsql=0

echo "$MODULES" | grep -qx 'pdo_mysql' && has_pdo_mysql=1
echo "$MODULES" | grep -qx 'mysqlnd' && has_mysqlnd=1
echo "$MODULES" | grep -qx 'pgsql' && has_pgsql=1
echo "$MODULES" | grep -qx 'pdo_pgsql' && has_pdo_pgsql=1
[ -n "$PHPINFO_LINE" ] && has_mysqlnd=1

PKG_NOTE=""
if have_cmd dpkg-query; then
  PKG_NOTE="$(dpkg-query -W -f='${Package} ${Version}\n' 'php7.4*' 2>/dev/null | paste -sd ';' -)"
elif have_cmd rpm; then
  PKG_NOTE="$(rpm -qa 2>/dev/null | grep -Ei '^php(|74|7\.4|74-)' | paste -sd ';' -)"
fi

# This plugin is specifically for 7.4.x < 7.4.30.
# Same CVEs also affect 8.0/8.1, but those belong to different checks/advisories.
if [[ ! "$PHP_VER" =~ ^7\.4\. ]]; then
  echo "UNKNOWN - installed PHP is $PHP_VER; Tenable 161971 specifically targets PHP 7.4.x < 7.4.30. Packages: ${PKG_NOTE:-none}"
  exit 2
fi

if ver_ge "$PHP_VER" "7.4.30"; then
  echo "PATCHED - PHP version is $PHP_VER (>= 7.4.30). Packages: ${PKG_NOTE:-none}"
  exit 0
fi

# Version is vulnerable upstream. Now assess whether the relevant extensions are present.
if [ $has_pdo_mysql -eq 1 ] && [ $has_mysqlnd -eq 1 ]; then
  echo "VULNERABLE - PHP $PHP_VER with pdo_mysql + mysqlnd loaded; matches CVE-2022-31626 exposure preconditions. Packages: ${PKG_NOTE:-none}"
  exit 1
fi

if [ $has_pgsql -eq 1 ] || [ $has_pdo_pgsql -eq 1 ]; then
  echo "VULNERABLE - PHP $PHP_VER with PostgreSQL extension loaded; matches CVE-2022-31625 exposure preconditions. Packages: ${PKG_NOTE:-none}"
  exit 1
fi

echo "UNKNOWN - PHP $PHP_VER is below 7.4.30, but the relevant extensions were not detected in this CLI context. Re-check the exact FPM/Apache SAPI config. Packages: ${PKG_NOTE:-none}"
exit 2
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning: do not mass-panic on every Tenable 161971 hit. First, slice the population to hosts that are both PHP 7.4.29 or older *and* actually use pdo_mysql/mysqlnd or PostgreSQL paths exposed to untrusted users; for this MEDIUM verdict there is no noisgate mitigation SLA — go straight to the 365-day remediation window, unless you discover exposed Adminer/phpMyAdmin-style workflows, which you should harden immediately as a local exception. Then complete the actual upgrade to 7.4.30+ or the relevant distro-fixed package inside the noisgate remediation SLA of ≤ 365 days, while separately treating the broader fact that PHP 7.4 is EOL as a platform-lifecycle problem you should retire sooner than that if possible.

Sources

  1. Tenable Nessus Plugin 161971
  2. PHP 7.4.30 Release Announcement
  3. PHP bug 81719 / CVE-2022-31626
  4. PHP bug 81720 / CVE-2022-31625
  5. NVD CVE-2022-31626
  6. NVD CVE-2022-31625
  7. Debian DSA-5179-1 php7.4 security update
  8. Gentoo GLSA 202209-20
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.