← Back to Feed CACHED · 2026-06-02 09:16:49 · CACHE_KEY tenable:95874
tenable:95874 · CWE-125 · Disclosed 2016-12-06

PHP 5.6.x < 5.6.29 Multiple Vulnerabilities

PHP WDDX empty boolean element memory corruption

ASSESSED — NOISGATE
Vendor
—
—
—
Reassessed
—
—
—
Verdict: —
Do you agree?
01 · The Real Story

This is a loaded nail gun locked inside a dusty closet, not a grenade rolling across the lobby

Tenable plugin 95874 flags PHP 5.6.x < 5.6.29 by banner and anchors on CVE-2016-9935, an out-of-bounds read / memory-corruption bug in PHP's ext/wddx parser when it handles an empty boolean element in a wddxPacket XML document. The same release also fixed an openssl_pbkdf2() crash bug (bug #72776, tied to CVE-2016-7132). Upstream fixed these in PHP 5.6.29 on 2016-12-08.

The vendor-style severity is inflated for most estates because the scary 9.8 score assumes the attacker can directly hit a vulnerable parsing path, but in reality they usually need a reachable application endpoint that feeds attacker-controlled XML into the deprecated WDDX extension. That extension was later deprecated and unbundled, which tells you how niche it became. So yes, old internet-facing PHP deserves attention, but this specific plugin is not a universal drop-everything critical unless you confirm real WDDX exposure.

"Severe bug, narrow real-world path: this is mostly a legacy PHP hygiene issue unless WDDX is actually reachable"
02 · The Attack Path

4 steps from start to impact.

STEP 01

Find a legacy PHP target

The attacker first identifies a host running old PHP, typically through headers, banners, error pages, or app fingerprinting. Tenable itself detects this plugin remotely from the reported PHP version, which is useful for inventory but says nothing about whether the dangerous parser path is reachable.
Conditions required:
  • Internet-facing or otherwise reachable web application
  • PHP version prior to 5.6.29
  • Version/banner disclosure or fingerprintable behavior
Where this breaks in practice:
  • Many sites suppress X-Powered-By or proxy PHP behind another stack
  • Banner detection overstates exploitability because it does not prove WDDX usage
  • Distro backports can complicate naive version-only triage
Detection/coverage: Nessus covers this as a remote version/banner finding. Credentialed package checks are better for separating true upstream version lag from distro-fixed builds.
STEP 02

Reach a WDDX deserialization sink

To turn version exposure into exploitability, the attacker needs an application path that passes attacker-controlled XML into wddx_deserialize() or equivalent ext/wddx functionality. Practical weaponization here is usually a custom curl/Python/XML PoC, not an off-the-shelf mass exploit kit.
Conditions required:
  • ext/wddx loaded in the target SAPI
  • Application accepts attacker-controlled WDDX/XML input
  • That input reaches the vulnerable parser
Where this breaks in practice:
  • WDDX is a niche, legacy feature and later became deprecated/unbundled
  • Most PHP applications never touch wddx_deserialize()
  • Even if WDDX is installed, there may be no reachable endpoint exposing it
Detection/coverage: Static code search for wddx_deserialize is high-signal. Dynamic scanners generally do not prove this sink exists.
STEP 03

Trigger the parser bug with crafted XML

The public PHP security bug report shows the trigger: a crafted wddxPacket containing an empty boolean element causes stack handling to go wrong inside php_wddx_push_element() / php_wddx_pop_element(). That can crash the PHP process and, in worst-case theory, open memory-corruption conditions.
Conditions required:
  • Attacker can submit crafted WDDX XML
  • Vulnerable parser path executes without prior sanitization
  • Target still runs an affected build
Where this breaks in practice:
  • Crash reliability is easier than controlled code execution
  • Memory-corruption exploitation quality varies by platform, build flags, and runtime layout
  • Modern hardening can reduce practical exploit reliability
Detection/coverage: Look for crashes in php-fpm, Apache worker logs, or core dumps around XML/WDDX parsing. Web logs may only show odd XML payloads, not a clear exploit signature.
STEP 04

Land impact: DoS in practice, possible worse on paper

If the parser path is reachable, the most defensible real-world outcome is denial of service through process crash or pool instability. The CVSS model allows for confidentiality and integrity impact because it is memory corruption, but public evidence of widespread reliable RCE chains for this exact bug is weak.
Conditions required:
  • PHP worker crash affects service availability
  • Target process privileges and memory layout permit further abuse
Where this breaks in practice:
  • No strong public record of modern in-the-wild weaponization
  • Attacker still needs the rare parser sink, not just an old PHP banner
  • Blast radius is usually one app pool / host, not instant fleet compromise
Detection/coverage: EDR can catch repeated worker crashes and anomalous child process behavior, but most orgs will see this first as app instability rather than a crisp exploit alert.
03 · Compensating Control

1
Disable or remove WDDX where unused — If the application does not require ext/wddx, remove it from the active PHP SAPI or disable the code path using wddx_deserialize(). For a MEDIUM finding there is no formal mitigation SLA, but this is the highest-value temporary control because it removes the decisive exploit sink while you work toward remediation within the 365-day remediation window.
2
Constrain internet reachability to legacy PHP pools — Put legacy PHP 5.6 apps behind tighter reverse-proxy ACLs, VPN-only access, or origin restrictions if they do not need broad public reach. There is no noisgate mitigation deadline for MEDIUM, but use this as a same-change-window hardening step for externally reachable systems while planning the actual upgrade inside the 365-day remediation window.
3
Verify package backports before declaring exposure — For distro-managed hosts, confirm package fix level with credentialed checks instead of trusting a remote banner alone. This avoids burning patch bandwidth on false positives while still meeting the MEDIUM remediation expectation.
4
Search code for wddx_deserialize and adjacent XML handlers — A quick code and config sweep tells you whether the scary CVSS path is real in your estate. Prioritize apps that are internet-facing and actually deserialize untrusted XML, then drive those first through the remediation window.
What doesn't work
  • Hiding the X-Powered-By header does not fix the parser bug; it only makes banner-based fingerprinting noisier.
  • A generic WAF rule is not a reliable answer because the risky condition is application-specific deserialization into WDDX, not one universal URI or signature.
  • Upgrading Apache or nginx alone does nothing if the vulnerable PHP runtime behind it is unchanged.
04 · Intelligence Metadata

The supporting signals.

Vendor severity reality checkTenable currently shows plugin 95874 as Critical with CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H and VPR 5.9 Medium; the user's HIGH (?) guess is outdated or from another view.
Primary bug in scopeCVE-2016-9935 is a WDDX parser memory-corruption issue in PHP < 5.6.29 and 7.0.x < 7.0.14; NVD maps it to CWE-125 Out-of-bounds Read.
Affected version rangeUpstream affected range is PHP 5.6.0 through 5.6.28; the Tenable plugin specifically keys on 5.6.x < 5.6.29 by remote banner.
Fixed versionsUpstream fix is 5.6.29. Distro backports exist, including Debian Jessie 5.6.29+dfsg-0+deb8u1; Ubuntu tracked fixes separately for older distro packages rather than upstream-style versioning.
In-the-wild statusI found no KEV listing and no credible public record of current broad exploitation campaigns for CVE-2016-9935. CISA has an old vulnerability bulletin entry, but not a Known Exploited Vulnerabilities catalog listing.
Proof-of-concept availabilityThere is a public trigger and patch context in PHP bug #73631, including sample WDDX XML and crash details from [email protected]. I did not find a mainstream Metasploit module or widely cited modern weaponized repo for this bug.
EPSSCVEDetails currently mirrors CVE-2016-9935 at about 4.39% EPSS and roughly the 89th percentile. Treat that as *moderate at most*, not emergency exploitation pressure.
Exposure telemetryPublic attack-surface tools can fingerprint old PHP banners, but they cannot tell you whether WDDX is enabled or whether a reachable wddx_deserialize() sink exists. CVEDetails shows coarse scanner telemetry claiming many affected IPs, but that is exposure noise, not proof of exploitability in your app.
Detection qualityThis plugin is a version-only remote finding: useful for finding stale PHP, weak for proving exploit path. The decisive validation step is a host-level check for PHP version plus whether the deployed codebase and active SAPI actually use WDDX.
Lifecycle contextPHP 5.6 is long end-of-life. Even if this specific parser bug is hard to reach, staying on 5.6 means you're betting production uptime on a dead runtime branch.

Sources.

  1. Tenable Nessus Plugin 95874
  2. PHP 5 ChangeLog - Version 5.6.29
  3. NVD - CVE-2016-9935
  4. PHP Security Bug #73631
  5. PHP Manual - WDDX
  6. PHP Supported Versions
  7. Debian DSA-3737-1
  8. Ubuntu CVE-2016-9935
05 · The Call

Final Verdict
↓ DOWNGRADED to MEDIUM (5.8/10)

Why this verdict

  • Start from 9.8, then cut for the sink requirement: vendor scoring assumes direct unauthenticated remote reachability to the vulnerable parser, but the real exploit needs attacker-controlled input to hit wddx_deserialize() or equivalent WDDX handling.
  • Deprecated feature, narrow population: WDDX was later deprecated and unbundled, which is strong evidence this is a legacy niche, not a core PHP path most modern apps exercise.
  • No strong exploitation pressure: no KEV entry, no strong modern campaign evidence, and only moderate EPSS means this is not behaving like a must-stop-everything edge-RCE despite the memory-corruption label.

Why not higher?

This is not higher because most estates with old PHP still will not expose a reachable WDDX parser sink to unauthenticated users. Also, public evidence leans much more toward crashability than toward a clean, repeatable, widely used RCE chain for this exact bug.

Why not lower?

This is not lower because the attacker needs no auth and no user interaction once the vulnerable parser path exists. Also, any externally reachable PHP 5.6 server is legacy debt with poor safety margin, so a pure backlog-only rating would understate operational risk.

06 · Verification

Crowdsourced verification payload.

Run this on the target host that actually executes PHP, not on your scanner. Invoke it as bash check_php_95874.sh /usr/bin/php (or point it at the exact php binary used by the affected pool/container); no root is required for a basic version/module check, but you may need shell access inside the container or VM.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check_php_95874.sh
# Determine likely exposure for Tenable plugin 95874 (PHP 5.6.x < 5.6.29).
# Usage: bash check_php_95874.sh /path/to/php
# Exit codes:
#   0 = PATCHED
#   1 = VULNERABLE
#   2 = UNKNOWN

set -u

PHPBIN="${1:-php}"

if ! command -v "$PHPBIN" >/dev/null 2>&1; then
  echo "UNKNOWN: PHP binary not found: $PHPBIN"
  exit 2
fi

VER="$($PHPBIN -r 'echo PHP_VERSION;' 2>/dev/null || true)"
if [ -z "$VER" ]; then
  echo "UNKNOWN: Unable to read PHP version from $PHPBIN"
  exit 2
fi

MODS="$($PHPBIN -m 2>/dev/null || true)"
WDDX_STATE="not-loaded"
if printf '%s
' "$MODS" | grep -qi '^wddx$'; then
  WDDX_STATE="loaded"
fi

# Normalize version: handle values like 5.6.28-1ubuntu4.21 or 5.6.29
BASE_VER="$(printf '%s' "$VER" | sed -E 's/[^0-9.].*$//')"

version_lt() {
  # returns 0 if $1 < $2
  [ "$(printf '%s
%s
' "$1" "$2" | sort -V | head -n1)" != "$2" ]
}

if printf '%s' "$BASE_VER" | grep -Eq '^5\.6\.[0-9]+$'; then
  if version_lt "$BASE_VER" "5.6.29"; then
    echo "VULNERABLE: PHP $VER detected (< 5.6.29); WDDX is $WDDX_STATE"
    exit 1
  else
    echo "PATCHED: PHP $VER is not in the affected upstream range; WDDX is $WDDX_STATE"
    exit 0
  fi
fi

# If it's not PHP 5.6.x, this specific Tenable plugin does not apply.
echo "PATCHED: PHP $VER is outside Tenable 95874's affected range (5.6.x < 5.6.29); WDDX is $WDDX_STATE"
exit 0