← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
CVE-2025-14177 · CWE-125 · Disclosed 2025-12-27

In PHP versions:8

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

This is a cracked peephole, not a kicked-in front door

CVE-2025-14177 is an uninitialized heap-memory disclosure in PHP getimagesize() affecting 8.1.x < 8.1.34, 8.2.x < 8.2.30, 8.3.x < 8.3.29, 8.4.x < 8.4.16, and 8.5.x < 8.5.1. The bug sits in php_read_stream_all_chunks(): during multi-chunk reads, the buffer pointer is not advanced, so later chunks overwrite the beginning while the tail remains uninitialized. In the vulnerable path, that stale heap content can land in returned JPEG APPn metadata such as APP1.

Vendor/NVD 7.5 HIGH overstates enterprise urgency because the real exploit chain is much narrower than a raw network CVSS suggests. An attacker does not get code execution, integrity loss, or a crash; they need an application that parses attacker-controlled images with getimagesize(..., $info), hits a multi-chunk read condition, and then exposes the returned metadata back to them or into another readable channel. That's a real bug and worth patching, but for most fleets it is backlog-worthy rather than fire-drill-worthy.

"Technically real, operationally narrow: this is a leak gadget, not an internet-scale PHP emergency."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Reach an upload or image-inspection code path

The attacker first needs a reachable application feature that accepts attacker-supplied image content and feeds it into PHP image metadata handling. In practice this is usually an upload validator, media pipeline, avatar handler, EXIF/IPTC parser, or custom content moderation flow. The weaponized input is just a crafted JPEG plus a normal HTTP upload client such as curl; the bug lives in the server-side PHP runtime, not in a network-facing daemon with its own banner.
Conditions required:
  • Unauthenticated or authenticated access to an app feature that accepts user-controlled image content
  • Backend is running a vulnerable PHP branch
  • Application actually invokes getimagesize() on attacker data
Where this breaks in practice:
  • Many PHP apps only check MIME types or use other libraries
  • A large share of internal PHP services never process untrusted images at all
  • Internet scanning cannot tell you whether a host reaches this exact function
Detection/coverage: VA scanners can flag vulnerable PHP package versions on-host, but external scanners generally cannot verify exploitability because the dangerous condition is application-code dependent.
STEP 02

Force the narrow vulnerable call shape

The vulnerable behavior matters when getimagesize(..., $info) collects APPn metadata and the read happens in multi-chunk mode. Upstream's PoC uses php://filter to guarantee chunking and demonstrate the bug, while the advisory notes exploitation on normal images is possible if the attacker can predict stream chunk behavior. The practical weapon is the upstream poc.php pattern plus a JPEG with a large APP1 segment.
Conditions required:
  • The app requests the second $info output parameter or otherwise consumes APPn metadata
  • Input is processed in a multi-chunk read scenario
  • JPEG/APPn metadata survives to the vulnerable parsing path
Where this breaks in practice:
  • Code that only asks for width/height without using $info dramatically reduces value
  • Multi-chunk reproduction is not guaranteed on every deployment
  • CISA ADP marks exploitation as poc and automatable: no
Detection/coverage: SAST or code search for getimagesize( with a second argument is more useful than perimeter scanning. Runtime telemetry rarely has a signature unless you log suspicious oversized APP segments.
STEP 03

Harvest leaked heap bytes from returned metadata

If the vulnerable path is hit, PHP can return corrupted APP1 or similar APPn content containing uninitialized heap bytes from the worker process. That can expose fragments of prior in-memory data such as tokens, request material, or other application residue. The tool here is the application's own response path: JSON, logs, previews, admin panels, or stored metadata that echoes attacker-controlled image metadata back out.
Conditions required:
  • Application returns, stores, logs, or otherwise exposes the APPn metadata to an attacker-readable channel
  • Leaked bytes contain something valuable in that worker's heap at that moment
Where this breaks in practice:
  • Many apps never return raw APPn metadata to end users
  • Leak quality is inconsistent and partial, not a guaranteed secret dump
  • Short-lived FPM workers and memory churn reduce repeatability
Detection/coverage: Look for anomalous large APP1/APPn values, binary-looking metadata in logs or API responses, and suspicious use of php://filter or repeated crafted JPEG uploads during testing.
STEP 04

Use the leak as a chain helper, not a standalone takeover

The realistic payoff is usually support for another attack, not a one-shot compromise. Heap disclosure can reduce uncertainty for exploit chains, expose secrets opportunistically, or confirm memory layout assumptions, but by itself this CVE does not modify data or execute code. The practical attacker toolkit would pair this with another app bug, stolen session workflow, or credential reuse opportunity.
Conditions required:
  • A second objective exists that benefits from partial memory disclosure
  • The leaked data includes something actionable
Where this breaks in practice:
  • No built-in RCE primitive
  • No integrity or availability impact
  • Post-leak operationalization is highly environment-specific
Detection/coverage: There is no clean network IOC for the chaining step; detection shifts to app telemetry, secret misuse, and abnormal session behavior.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo authoritative public evidence of active exploitation found. Not listed in CISA KEV as of the catalog pages reviewed.
PoC availabilityYes. The upstream GitHub advisory includes a minimal PoC (poc.php) and the fix commit adds regression test gh20584.phpt demonstrating the vulnerable path.
EPSS0.00025 from your intel — effectively background-noise probability, which fits the narrow and non-automatable chain.
KEV / exploitation metadataKEV: No. CISA ADP/Vulnrichment on the CVE record labels exploitation as poc, automatable: no, technical impact: partial.
CVSS reality checkNVD shows CVSS v3.1 7.5 HIGH, but the PHP CNA's CVSS v4.0 is only 6.3 MEDIUM because it recognizes high complexity and attack requirements present.
Affected versions8.1.x < 8.1.34, 8.2.x < 8.2.30, 8.3.x < 8.3.29, 8.4.x < 8.4.16, 8.5.x < 8.5.1.
Fixed versions / backportsUpstream fixed in 8.1.34, 8.2.30, 8.3.29, 8.4.16, 8.5.1. Distros backport: Ubuntu 24.04 fixed php8.3 8.3.6-0ubuntu0.24.04.6; Ubuntu 25.04 fixed php8.4 8.4.5-1ubuntu1.2; Debian bookworm fixed php8.2 8.2.30-1~deb12u1; Debian trixie fixed php8.4 8.4.16-1~deb13u1.
Exposure / scanning realityThere is no decision-grade internet fingerprint for this bug. Shodan/Censys-style counts for 'PHP' do not prove vulnerable runtime version, app reachability, getimagesize(..., $info) use, or metadata exposure.
Disclosure timelinePublic advisory and releases landed 2025-12-18; CVE/NVD publication followed on 2025-12-27; NVD analysis update shows 2026-01-08.
ReporterReported by Nikita Sveshnikov (Positive Technologies).
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to LOW (3.8/10)

The decisive factor is that exploitability depends on a very specific application behavior: attacker-controlled image parsing through getimagesize(..., $info) with a multi-chunk read and an attacker-readable metadata sink. That collapses the reachable population well below what a generic AV:N/PR:N/UI:N CVSS line implies, and the impact remains confidentiality-only and partial even when hit.

HIGH Technical existence of the bug and fixed version ranges
MEDIUM Enterprise-wide exploitability reduction due to application-specific preconditions
MEDIUM Absence of public in-the-wild exploitation at time of review

Why this verdict

  • Downgrade for app-path dependence: the attacker needs more than 'a PHP server on the internet' — they need a reachable code path that passes attacker content into getimagesize().
  • Downgrade again for narrow API usage: meaningful leakage depends on the $info metadata path, not just width/height probing, which materially shrinks the exposed population.
  • Downgrade again for exploit friction: multi-chunk behavior is a prerequisite; the CVE record itself reflects this with CVSS v4 AC:H and AT:P, and CISA ADP marks it automatable: no.
  • Downgrade again for blast radius: this is an info leak, not RCE; no integrity or availability impact, and the attacker still needs a way to read the leaked APPn data back out.
  • Do not downgrade to ignore: upstream published a PoC, the bug is in a ubiquitous runtime, and any public-facing upload workflow that reflects metadata turns this into a real confidentiality issue.

Why not higher?

There is no native code-execution, overwrite, or denial-of-service primitive here. More importantly, the attack chain stacks multiple real-world prerequisites — untrusted image handling, the right getimagesize() usage, multi-chunk conditions, and an exposed metadata sink — which means most vulnerable PHP installs are not directly exploitable in a useful way.

Why not lower?

This is still a genuine memory disclosure in a widely deployed runtime, not a theoretical lint finding. If you run internet-facing PHP applications that parse user uploads and surface EXIF/IPTC or APP metadata, an unauthenticated attacker may be able to extract process-memory residue without any prior foothold.

05 · Compensating Control

What to do — in priority order.

  1. Inventory getimagesize() callers — Identify applications that call getimagesize( on user-controlled content, especially code that supplies the second $info parameter or stores/returns image metadata. For a LOW verdict there is no mitigation SLA, so do this as backlog hygiene while preparing the patch path.
  2. Stop reflecting raw APP/EXIF/IPTC metadata — If your app returns or stores raw metadata from uploaded images, strip or discard it before user-visible output. This directly breaks the attacker-readable sink that makes the leak useful; with LOW severity, handle during normal engineering work before the remediation window closes.
  3. Constrain upload pathways — Gate image-processing endpoints behind auth where feasible, rate-limit anonymous uploads, and prefer transcoding or metadata stripping before downstream handling. This reduces reachable population and dampens repeated probing, but because the verdict is LOW, treat it as routine hardening rather than emergency mitigation.
  4. Patch to distro-fixed builds — Prefer vendor-backported distro packages over raw upstream comparisons when you are on Ubuntu/Debian/SUSE platform builds. This is the cleanest durable fix; for LOW, there is no mitigation SLA and the patch belongs in backlog remediation.
What doesn't work
  • A generic WAF will not reliably stop this because the bug is triggered inside normal image-processing logic, often on legitimate multipart uploads.
  • EDR on the host may see the PHP process but usually cannot tell that returned APP1 bytes contain uninitialized heap data.
  • Blocking obvious php://filter strings alone is insufficient; upstream states exploitation on normal images can still be possible with known chunk behavior.
  • Simply hiding the PHP version banner does nothing; the hard part for the attacker is the application code path, not the banner.
06 · Verification

Crowdsourced verification payload.

Run this on the target PHP host as a local auditor or via your config-management/remote-exec tooling. Invoke it as bash check-cve-2025-14177.sh or bash check-cve-2025-14177.sh /usr/bin/php; no root is required for the basic version check, but package-manager backport detection works best with normal local package-query access.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check-cve-2025-14177.sh
# Detect likely exposure to CVE-2025-14177 on Linux hosts.
# Output: VULNERABLE / PATCHED / UNKNOWN
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

set -u

PHP_BIN="${1:-php}"

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

emit() {
  local status="$1"; shift
  echo "$status: $*"
  case "$status" in
    PATCHED) exit 0 ;;
    VULNERABLE) exit 1 ;;
    *) exit 2 ;;
  esac
}

if ! have "$PHP_BIN"; then
  emit UNKNOWN "PHP binary '$PHP_BIN' not found"
fi

raw_ver="$($PHP_BIN -v 2>/dev/null | head -n1 || true)"
if [ -z "$raw_ver" ]; then
  emit UNKNOWN "Unable to read PHP version from '$PHP_BIN -v'"
fi

# Extract first version-looking token, e.g. 8.3.6 or 8.3.6-0ubuntu0.24.04.6
full_token="$(printf '%s' "$raw_ver" | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+([.-][A-Za-z0-9:+~._-]+)?' | head -n1)"
base_ver="$(printf '%s' "$full_token" | grep -Eo '^[0-9]+\.[0-9]+\.[0-9]+' | head -n1)"

if [ -z "$base_ver" ]; then
  emit UNKNOWN "Could not parse version from: $raw_ver"
fi

major_minor="$(printf '%s' "$base_ver" | cut -d. -f1,2)"

# Distro backport checks first when package metadata is available.
check_dpkg() {
  have dpkg-query || return 1
  local pkg ver
  for pkg in php php8.1 php8.2 php8.3 php8.4; do
    ver="$(dpkg-query -W -f='${Version}' "$pkg" 2>/dev/null | head -n1)"
    [ -n "$ver" ] || continue
    case "$pkg:$ver" in
      php8.3:8.3.6-0ubuntu0.24.04.6*|php8.4:8.4.5-1ubuntu1.2*|php8.4:8.4.11-1ubuntu1.1*|php8.2:8.2.30-1~deb12u1*|php8.2:8.2.31-1~deb12u1*|php8.4:8.4.16-1~deb13u1*|php8.4:8.4.21-1~deb13u1*|php7.4:7.4.33-1+deb11u11*)
        emit PATCHED "Detected distro-fixed package $pkg $ver for CVE-2025-14177"
        ;;
    esac
  done
  return 1
}

check_rpm() {
  have rpm || return 1
  local q
  q="$(rpm -qa 2>/dev/null | grep -E '^php(|8\.[0-9]+)(-|$)' | sort | head -n20 || true)"
  [ -n "$q" ] || return 1
  # Conservative RPM logic: if the installed runtime reports an upstream-fixed base version, trust it.
  return 1
}

check_dpkg || true
check_rpm || true

case "$major_minor" in
  8.1)
    if ver_lt "$base_ver" "8.1.34"; then
      emit VULNERABLE "PHP $base_ver is in affected range for CVE-2025-14177 (< 8.1.34)"
    else
      emit PATCHED "PHP $base_ver is at or above upstream fix 8.1.34"
    fi
    ;;
  8.2)
    if ver_lt "$base_ver" "8.2.30"; then
      emit VULNERABLE "PHP $base_ver is in affected range for CVE-2025-14177 (< 8.2.30)"
    else
      emit PATCHED "PHP $base_ver is at or above upstream fix 8.2.30"
    fi
    ;;
  8.3)
    if ver_lt "$base_ver" "8.3.29"; then
      emit VULNERABLE "PHP $base_ver is in affected range for CVE-2025-14177 (< 8.3.29)"
    else
      emit PATCHED "PHP $base_ver is at or above upstream fix 8.3.29"
    fi
    ;;
  8.4)
    if ver_lt "$base_ver" "8.4.16"; then
      emit VULNERABLE "PHP $base_ver is in affected range for CVE-2025-14177 (< 8.4.16)"
    else
      emit PATCHED "PHP $base_ver is at or above upstream fix 8.4.16"
    fi
    ;;
  8.5)
    if ver_lt "$base_ver" "8.5.1"; then
      emit VULNERABLE "PHP $base_ver is in affected range for CVE-2025-14177 (< 8.5.1)"
    else
      emit PATCHED "PHP $base_ver is at or above upstream fix 8.5.1"
    fi
    ;;
  7.4|8.0)
    emit PATCHED "Installed branch $major_minor is not in the affected upstream version ranges for this CVE"
    ;;
  *)
    emit UNKNOWN "Parsed PHP version $base_ver; branch not covered by this checker"
    ;;
esac
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning: query your fleet for vulnerable PHP branches, then separately identify the smaller subset of apps that process untrusted images and use getimagesize() metadata paths. Because this is a LOW reassessment, there is no noisgate mitigation SLA — treat it as backlog hygiene unless your app explicitly reflects image metadata, and work to complete patching within the noisgate remediation SLA for LOW issues by folding the vendor fix into normal maintenance rather than burning an emergency window.

Sources

  1. PHP GitHub Security Advisory GHSA-3237-qqm7-mfv7
  2. NVD CVE-2025-14177
  3. PHP 8 ChangeLog
  4. PHP fix commit c5f28c7
  5. Debian Security Tracker
  6. Ubuntu CVE page
  7. CISA Known Exploited Vulnerabilities Catalog
  8. OpenCVE record with CISA ADP Vulnrichment details
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.