This is a spare key left under the mat inside a locked apartment building
CVE-2018-10545 affects PHP-FPM in upstream PHP before 5.6.35 and later fixed branches 7.0.29 / 7.1.16 / 7.2.4. The bug is not remote code execution; it is a local information disclosure / security-bypass issue where dumpable PHP-FPM worker processes let one local user dump another pool worker's memory and read secrets from shared opcache-backed state. In practice, the attacker needs local execution on the same Linux host, PHP-FPM in use, separate pools, and a multi-user setup where hostile and victim workloads coexist.
The low-ish vendor framing matches reality better than the scarier wording in some scanners. For a normal enterprise web tier, this is post-compromise, same-host, same-platform, narrow-topology abuse with very limited reachable population; it matters mostly for shared hosting or other deliberately multi-tenant Linux PHP-FPM estates that grant shell or code execution to mutually untrusted users.
5 steps from start to impact.
Get a same-host foothold with bash or a webshell
- Attacker already has local execution on the target Linux host
- Target uses PHP-FPM rather than only CLI or mod_php
- Vulnerable upstream or equivalent unpatched build is installed
- Requires a prior compromise stage or intentionally shared-hosting model
- Most enterprise app servers do not expose arbitrary shell access to untrusted users
- If the foothold is in a container isolated from the FPM host, the path often dies here
Locate a dumpable PHP-FPM worker with ps
ps, the attacker identifies active php-fpm worker PIDs. The vulnerable behavior comes from PHP-FPM setting PR_SET_DUMPABLE, which re-enables ptrace/core-dump access in cases where it should have remained blocked after UID/GID changes.- At least one PHP-FPM worker process is running
- Workers are handling or recently handled victim application data
- No worker, no dump
- Single-tenant deployments remove the cross-account value proposition
- Minimal process visibility or namespaces can complicate PID discovery
Dump memory with gcore / ptrace
gcore <pid> or equivalent ptrace tooling against a PHP-FPM worker. In the reporter's demonstrated case, this produced a core dump readable by another local user, exposing data that opcache permission checks were supposed to isolate.- Attacker can ptrace or core-dump the target worker
- Kernel hardening does not block the action
kernel.yama.ptrace_scope, hardened containers, or restricted core-dump policy can stop this cold- Some EDR products alert on
gcore,gdb, or abnormal ptrace activity - The attacker still needs the right victim process at the right time
gcore, gdb, or ptrace events are monitored; otherwise low.Mine secrets from the core file with strings
strings or more specialized memory analysis to recover database credentials, API tokens, or application secrets from victim PHP memory. The public bug report explicitly demonstrated recovery of WordPress database credentials from another account's process memory.- Victim secrets were resident in memory
- The dump file is readable to the attacker
- Not every dump contains useful secrets
- Secrets may be short-lived or masked by workload timing
- Impact is usually confidentiality theft, not direct host takeover by itself
strings/file reads are visible to host telemetry if enabled.Pivot with stolen app credentials
- Recovered secrets are valid and reusable
- Neighboring applications share infrastructure worth pivoting into
- Blast radius is typically confined to one host and adjacent app identities
- Credential rotation, network ACLs, and DB auth separation limit the follow-on value
- This is still downstream of an initial local foothold
The supporting signals.
| In-the-wild status | No credible active exploitation evidence found in the reviewed sources; this CVE is better characterized as a niche post-compromise abuse path than a campaign driver. |
|---|---|
| KEV status | Not listed in CISA KEV in the reviewed catalog source; no KEV add date located. |
| PoC / exploit availability | Public reproduction steps exist in the PHP bug report (gcore on a PHP-FPM worker, then strings on the dump). I did not find a widely adopted turnkey GitHub exploit that materially changes defender urgency. |
| EPSS | Very low by available mirrors: roughly 0.04% probability / ~14th percentile from public EPSS mirrors of FIRST data, which fits the narrow local-only reach. |
| CVSS vector meaning | CVSS:3.0/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:N/A:N means local attack vector, high complexity, low privileges required, and confidentiality-only impact. |
| Affected versions | Upstream PHP < 5.6.35, 7.0.x < 7.0.29, 7.1.x < 7.1.16, 7.2.x < 7.2.4 when PHP-FPM on Linux is in play. |
| Fixed versions | Upstream fixed in 5.6.35 / 7.0.29 / 7.1.16 / 7.2.4. Debian tracker also shows backports such as jessie 5.6.36+dfsg-0+deb8u1 and stretch 7.0.30-0+deb9u1. |
| Exposure population | Internet exposure is the wrong lens here. Shodan/Censys can find PHP-facing services, but they cannot tell you whether an attacker already has same-host local execution plus a dumpable cross-tenant PHP-FPM topology. |
| Disclosure timeline | Bug submitted 2017-11-30; upstream fix shipped in PHP 5.6.35 on 2018-03-29; NVD published the CVE on 2018-04-29. |
| Reporter / researcher | Reported by jd@cpanel.net in PHP bug #75605; Red Hat later summarized shared-hosting as the most obvious exploitation case. |
noisgate verdict.
The decisive factor is attacker position: this bug starts at local execution on the same Linux host, which means the attacker is already past initial access and sitting in a very specific PHP-FPM deployment model. In a 10,000-host enterprise estate, that sharply limits both reachable population and incremental blast radius, so this does not deserve scarce patch capacity as a standalone emergency.
Why this verdict
- Downward pressure: local-only — the NVD vector is
AV:L; this is not reachable from the internet without a separate compromise step first. - Downward pressure: post-initial-access topology — needing same-host execution implies the attacker already beat your perimeter, app controls, or tenant boundary before this CVE matters.
- Downward pressure: narrow real-world population — the bug is most relevant to shared hosting / mutually untrusted multi-user PHP-FPM setups, not ordinary enterprise app servers.
- Downward pressure: modern controls can interrupt it — ptrace restrictions, container isolation, and EDR coverage on
gcore/gdbmaterially raise practical friction. - Limited blast radius — even when exploited, the outcome is usually theft of neighboring app secrets from one host, not universal domain compromise.
Why not higher?
There is no unauthenticated remote path here, no wormability, and no evidence that this vulnerability by itself opens broad enterprise attack surface. The attack chain assumes prior local code execution plus a very particular hosting model, which is exactly the kind of compounding friction that should crush severity.
Why not lower?
It is not pure noise if you actually run multi-tenant Linux PHP-FPM with untrusted co-resident users or workloads. In that niche, it can expose real secrets and defeat assumptions around opcache isolation, so I would not call it nonexistent risk.
What to do — in priority order.
- Document applicability — If your environment is a normal enterprise web tier with no untrusted same-host users, no action is required for this CVE; document the post-compromise/local-only rationale and move on. If you *do* run shared hosting or customer shell access, record those assets as exceptions and treat them separately.
- Restrict ptrace and core dumps — On shared-hosting-style Linux systems, enforce
kernel.yama.ptrace_scope, restrictgcore/gdb, and tighten core-dump policy so unprivileged users cannot dump neighboring PHP-FPM workers. Because the noisgate verdict is IGNORE, there is no SLA here unless the host is one of those narrow multi-tenant exceptions. - Collapse unnecessary co-tenancy — Do not place mutually untrusted apps or users in adjacent PHP-FPM pools on the same host if you can avoid it. This removes the cross-tenant memory theft value even when a local foothold exists.
- A WAF does not help; exploitation happens after local foothold and uses host debugging/core-dump behavior, not HTTP payload tricks.
- MFA does not help directly; the attacker is not logging into the app as a user, they are dumping worker memory after obtaining local execution.
- External internet scanning does not prove safety; the key prerequisites are same-host local access and tenant layout, which scanners cannot infer.
Crowdsourced verification payload.
Run this on the target Linux host as a local auditor. Invoke it with sudo bash check_cve_2018_10545.sh for best results because reading pool configs and package metadata is easier with root, though it often works unprivileged; it checks for PHP-FPM presence, upstream vulnerable version windows, and whether the host appears to use multiple distinct pool users.
#!/usr/bin/env bash
# check_cve_2018_10545.sh
# Determine likely exposure to CVE-2018-10545 (PHP-FPM dumpable child processes)
# Outputs one of: VULNERABLE / PATCHED / UNKNOWN
# Exit codes: 0 PATCHED, 1 VULNERABLE, 2 UNKNOWN
set -u
out_unknown() { echo "UNKNOWN: $1"; exit 2; }
out_vuln() { echo "VULNERABLE: $1"; exit 1; }
out_patched() { echo "PATCHED: $1"; exit 0; }
have_cmd() { command -v "$1" >/dev/null 2>&1; }
ver_lt() {
# returns 0 if $1 < $2 using sort -V
[ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)" = "$1" ] && [ "$1" != "$2" ]
}
ver_ge() {
[ "$1" = "$2" ] && return 0
! ver_lt "$1" "$2"
}
phpfpm_bin=""
for c in php-fpm php-fpm5 php-fpm7.0 php-fpm7.1 php-fpm7.2 php-fpm7.3 php-fpm7.4 php-fpm8.0 php-fpm8.1 php-fpm8.2 php-fpm8.3; do
if have_cmd "$c"; then phpfpm_bin="$c"; break; fi
done
pkg_ver=""
raw_ver=""
if [ -n "$phpfpm_bin" ]; then
raw_ver="$($phpfpm_bin -v 2>/dev/null | head -n1)"
pkg_ver="$(printf '%s' "$raw_ver" | sed -n 's/.*PHP \([0-9][0-9.]*\).*/\1/p')"
fi
if [ -z "$pkg_ver" ]; then
if have_cmd dpkg-query; then
for p in php5-fpm php-fpm php7.0-fpm php7.1-fpm php7.2-fpm php7.3-fpm php7.4-fpm php8.0-fpm php8.1-fpm php8.2-fpm php8.3-fpm; do
v="$(dpkg-query -W -f='${Version}' "$p" 2>/dev/null | head -n1)"
if [ -n "$v" ]; then
raw_ver="$v"
pkg_ver="$(printf '%s' "$v" | sed -n 's/^\([0-9][0-9.]*\).*/\1/p')"
break
fi
done
elif have_cmd rpm; then
for p in php-fpm php56-php-fpm php70-php-fpm php71-php-fpm php72-php-fpm php73-php-fpm php74-php-fpm php80-php-fpm php81-php-fpm php82-php-fpm php83-php-fpm; do
v="$(rpm -q --qf '%{VERSION}-%{RELEASE}' "$p" 2>/dev/null)"
if [ -n "$v" ] && ! printf '%s' "$v" | grep -q 'not installed'; then
raw_ver="$v"
pkg_ver="$(printf '%s' "$v" | sed -n 's/^\([0-9][0-9.]*\).*/\1/p')"
break
fi
done
fi
fi
[ -n "$pkg_ver" ] || out_unknown "php-fpm not found or version could not be determined"
# Determine whether the upstream version falls in a vulnerable window.
upstream_vuln="no"
if ver_ge "$pkg_ver" "5.6.0" && ver_lt "$pkg_ver" "5.6.35"; then upstream_vuln="yes"; fi
if ver_ge "$pkg_ver" "7.0.0" && ver_lt "$pkg_ver" "7.0.29"; then upstream_vuln="yes"; fi
if ver_ge "$pkg_ver" "7.1.0" && ver_lt "$pkg_ver" "7.1.16"; then upstream_vuln="yes"; fi
if ver_ge "$pkg_ver" "7.2.0" && ver_lt "$pkg_ver" "7.2.4"; then upstream_vuln="yes"; fi
# If version is outside affected windows, call it patched.
if [ "$upstream_vuln" = "no" ]; then
out_patched "Detected PHP-FPM version $pkg_ver is outside upstream vulnerable ranges"
fi
# Look for FPM pool configs and count distinct users.
conf_dirs="/etc/php-fpm.d /etc/php*/fpm/pool.d /usr/local/etc/php-fpm.d"
users=""
for d in $conf_dirs; do
[ -d "$d" ] || continue
while IFS= read -r -d '' f; do
u="$(grep -E '^[[:space:]]*user[[:space:]]*=' "$f" 2>/dev/null | tail -n1 | sed 's/.*=//; s/[[:space:]]//g')"
[ -n "$u" ] && users="$users
$u"
done < <(find "$d" -maxdepth 1 -type f \( -name '*.conf' -o -name '*.pool' \) -print0 2>/dev/null)
done
distinct_users="$(printf '%s
' "$users" | sed '/^$/d' | sort -u | wc -l | tr -d ' ')"
# Heuristic: vulnerable upstream version + multiple pool users => likely exposed.
# Single-user deployments are often not meaningfully exposed to the cross-tenant angle.
if [ "$distinct_users" -ge 2 ]; then
out_vuln "Upstream vulnerable PHP-FPM version $pkg_ver with multiple distinct pool users detected ($distinct_users users); check for distro backports before patching"
fi
# Backport caveat for distro builds.
if printf '%s' "$raw_ver" | grep -Eq 'deb|ubuntu|el[0-9]|fc[0-9]|suse'; then
out_unknown "Version string '$raw_ver' may include distro backports; upstream version looks vulnerable, but package maintenance could already include the fix"
fi
out_unknown "Upstream vulnerable PHP-FPM version $pkg_ver detected, but host does not clearly appear multi-tenant; verify package backports and pool topology manually"If you remember one thing.
Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.