← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
tenable:118956 · Disclosed 2018-11-06

nginx 1

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

This is a pressure valve problem, not a front-door master key

Tenable plugin 118956 rolls up three nginx flaws fixed on 2018-11-06 in 1.14.1 and 1.15.6: two HTTP/2 resource-exhaustion bugs (CVE-2018-16843, CVE-2018-16844) and one ngx_http_mp4_module crash/memory-disclosure bug (CVE-2018-16845). The HTTP/2 issues affect 1.9.5-1.15.5 only when nginx is built with ngx_http_v2_module and a listen ... http2 path is actually configured; the MP4 issue affects 1.1.3-1.15.5 plus 1.0.7-1.0.15 only when nginx is built with ngx_http_mp4_module, the mp4 directive is used, and a crafted MP4 can be made to flow through that code path.

The MEDIUM label is basically right in enterprise reality. NVD's 7.5 HIGH for the HTTP/2 pair assumes a clean unauthenticated network DoS path, but real deployments add friction: optional build flags, specific config directives, and impact that is generally availability degradation on one web tier node, not takeover. Public internet reachability keeps this above LOW, but lack of KEV/active-exploitation evidence and the feature-gated attack surface keep it well below HIGH.

"Public-facing but mostly DoS-only, and the exploitable paths depend on optional nginx features being enabled."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Find a listener that actually exposes the vulnerable feature

The attacker first fingerprints nginx and checks whether the target really accepts HTTP/2 or serves MP4 through nginx. Typical tooling here is curl, nghttp, or nmap/http2 probes for the HTTP/2 path, and ordinary content discovery for the MP4 path. This matters because version-only findings overstate exposure when the vulnerable module is present in code but not reachable in config.
Conditions required:
  • Internet or internal network path to the nginx listener
  • For CVE-2018-16843/16844: HTTP/2 enabled on a live listen socket
  • For CVE-2018-16845: MP4 content routed through ngx_http_mp4_module
Where this breaks in practice:
  • Upstream advisories state both ngx_http_v2_module and ngx_http_mp4_module are not built by default
  • Many scanners only read the Server header and do not verify http2 or mp4 directives
  • Distro backports can make old-looking package versions patched
Detection/coverage: External scanners like Nessus catch the version/header condition well, but they generally do not prove http2 or mp4 is actually enabled. Local config audit or nginx -T review is needed.
STEP 02

Trigger the HTTP/2 exhaustion path with frame abuse

For the HTTP/2 pair, the attacker uses an HTTP/2 client such as nghttp2 (nghttp/h2load) to send crafted frame patterns that drive excessive memory or excessive CPU consumption. The vendor advisory ties both flaws directly to the HTTP/2 implementation and an enabled listen ... http2 configuration. This is unauthenticated and remote once the feature is exposed.
Conditions required:
  • nginx version in the vulnerable HTTP/2 range
  • ngx_http_v2_module present
  • listen path configured for http2
Where this breaks in practice:
  • Only availability is at stake; there is no code execution path here
  • Reverse proxies, autoscaling, and health-checked load balancers can dilute single-node impact
  • Rate limiting, connection caps, or upstream CDN buffering can reduce attacker efficiency
Detection/coverage: Look for spikes in HTTP/2 sessions, unusual frame/error patterns, worker CPU saturation, and memory pressure. Version-only scanners detect exposure; runtime abuse shows up better in nginx error logs, host telemetry, and L7 edge metrics.
STEP 03

Starve workers and degrade the web tier

If the crafted HTTP/2 traffic lands cleanly, worker processes burn CPU or memory until the instance slows, sheds connections, or gets restarted by orchestration. In a clustered estate, the blast radius is usually one pool or node at a time unless every edge server shares the same config and no upstream protection exists. This is an operational availability hit, not a privilege boundary break.
Conditions required:
  • Sustained request path to the targeted listener
  • Insufficient headroom or weak admission controls on the affected tier
Where this breaks in practice:
  • Modern load balancers can drain sick nodes quickly
  • CDNs and WAFs sometimes terminate HTTP/2 before nginx ever sees malicious frames
  • Autoscaling can mask the effect even if the bug is real
Detection/coverage: EDR will not help much here; infra telemetry is the better detector. Watch for worker restarts, pod evictions, CPU steal, OOM events, and surge in 502/503s.
STEP 04

Alternate path: feed a crafted MP4 into ngx_http_mp4_module

For CVE-2018-16845, the attacker uses a crafted MP4 file—commonly easy to generate or mutate with tools like ffmpeg plus hex editing—and causes nginx to process it through the mp4 directive path. Per nginx, this can cause an infinite loop, worker crash, or worker-memory disclosure. In practice this path is narrower than the HTTP/2 pair because it requires both the module and a content-processing workflow that many enterprises do not enable.
Conditions required:
  • Vulnerable version range for the MP4 bug
  • ngx_http_mp4_module present
  • mp4 directive used on attacker-reachable content
  • Attacker can upload, place, or otherwise trigger processing of a crafted MP4
Where this breaks in practice:
  • This is a specific application workflow, not a generic nginx exposure
  • Many orgs serve static media from object storage/CDN instead of nginx mp4 processing
  • Upload validation or media re-encoding often breaks the crafted file before nginx sees it
Detection/coverage: Pure network scanners usually miss this entirely. You need local config review plus application-path testing of MP4 endpoints to know whether the bug is reachable.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusI found no CISA KEV listing and no authoritative source in this review showing active exploitation campaigns. Treat this as no proven active exploitation evidence found, not as proof of absence.
Proof-of-concept availabilitycvefeed.io reports 23 public GitHub PoCs for CVE-2018-16843, 18 for CVE-2018-16844, and 20 for CVE-2018-16845. The original nginx vendor material published advisories and an MP4 patch, not a weaponized exploit.
Reporter / researchernginx credits Gal Goldshtein of F5 Networks for the initial report of the HTTP/2 CPU issue in the advisory for CVE-2018-16844.
EPSS snapshotMirror data surfaced via Vulners shows EPSS approximately 0.58348 for CVE-2018-16843, 0.10883 for CVE-2018-16844, and 0.06332 for CVE-2018-16845. Use with caution: EPSS is probability, not impact, and mirrors may lag FIRST slightly.
KEV statusNo matching CVE entries surfaced from the CISA KEV catalog during this assessment.
CVSS disagreementNVD scores the HTTP/2 bugs at 7.5 HIGH (AV:N/AC:L/PR:N/UI:N/A:H), while Red Hat/CNA scored them 5.3 MEDIUM. For CVE-2018-16845, NVD shows 6.1 MEDIUM while Red Hat/CNA shows **8.2 HIGH`; that spread is a signal that exploit preconditions materially change the practical risk.
Affected versionsPer nginx advisories: HTTP/2 issues hit 1.9.5-1.15.5; MP4 issue hits 1.1.3-1.15.5 and 1.0.7-1.0.15. All three are fixed in 1.14.1 and 1.15.6 for upstream nginx.
Fixed versions and backportsUpstream fix is 1.14.1 / 1.15.6. Debian backported fixes to stretch 1.10.3-1+deb9u2; Ubuntu backported to 18.10 1.15.5-0ubuntu2.1, 18.04 LTS 1.14.0-0ubuntu1.2, 16.04 LTS 1.10.3-0ubuntu0.16.04.3, and 14.04 LTS 1.4.6-1ubuntu3.9.
Exposure populationThis matters because nginx is everywhere: Netcraft's November 2018 survey put nginx at 25.53% of the top million busiest sites and 27.40% of active sites. Broad product prevalence justifies watching it, but the vulnerable *feature path* is still narrower than the product footprint.
Scanner caveatTenable plugin 118956 is a remote, header/version-based finding. That is good for fleet discovery, but weak for deciding urgency because it does not prove the target actually enables http2 or mp4, and it can overfire on backported distro packages.
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to MEDIUM (5.6/10)

The decisive factor is attack-path friction: every path here is gated by optional nginx features, and the dominant impact is denial of service, not code execution or privilege gain. Public exposure keeps the issue relevant, but there is no strong evidence in these sources that attackers are actively prioritizing this bug set in the wild.

HIGH Affected/fixed version ranges and feature prerequisites
MEDIUM Real-world exploitation prevalence

Why this verdict

  • Publicly reachable but mostly DoS-only — the HTTP/2 path can be hit remotely without auth, but the practical consequence is service degradation or worker exhaustion, not host compromise.
  • Feature-gated exposure — CVE-2018-16843/16844 require ngx_http_v2_module *and* a live listen ... http2 config; CVE-2018-16845 additionally requires ngx_http_mp4_module, an active mp4 directive, and an attacker-reachable crafted MP4 workflow.
  • Version-only scanners overstate risk — Tenable detects by Server header/version and cannot prove the vulnerable code path is reachable; that creates a lot of false urgency in distro-backported or feature-disabled estates.

Why not higher?

It is not HIGH because the chain lacks a strong amplifier like RCE, auth bypass, or tenant-wide compromise. The main HTTP/2 bugs are resource-consumption flaws, and the MP4 issue needs a narrow media-processing path that many enterprises simply do not expose.

Why not lower?

It is not LOW because nginx is massively deployed and internet-facing, and the HTTP/2 path can be reached by unauthenticated remote attackers when enabled. Even a DoS-only flaw matters on revenue-facing edge tiers, especially if you have concentrated ingress through a small number of reverse proxies.

05 · Compensating Control

What to do — in priority order.

  1. Validate feature reachability before escalating — Run a local config audit now to determine whether affected hosts actually enable http2 or mp4. For a MEDIUM verdict there is no mitigation SLA; use this check to separate real exposure from version-only noise and go straight into the remediation queue.
  2. Disable unused HTTP/2 listeners — If you do not need HTTP/2 on a given edge tier, remove http2 from listen statements or terminate HTTP/2 upstream at the CDN/load balancer instead. This meaningfully cuts the only broad unauthenticated path while you work through the 365-day remediation window.
  3. Remove mp4 processing where possible — If the mp4 directive is present, move media serving to static delivery or a CDN/object store path and stop sending attacker-controlled MP4s through nginx parsing logic. That neutralizes the narrowest but messiest path without waiting for a binary upgrade.
  4. Cap abusive connection behavior at the edge — Use CDN, reverse proxy, or load balancer controls for connection/request concurrency and per-client rate limits to reduce the impact of resource-exhaustion attempts. This is compensating hardening, not a substitute for patching, and for MEDIUM there is no mitigation SLA forcing an emergency change.
  5. Watch for backport false positives — Before creating mass work orders, reconcile package versions against distro advisories such as Debian and Ubuntu backports. Many old-looking versions are already fixed, and wasting change windows on those is how patch programs lose credibility.
What doesn't work
  • A generic WAF rule is not a reliable answer; these bugs live in protocol handling and module logic, so signature coverage is inconsistent and often bypassable.
  • MFA does nothing here because the reachable path is on the web server itself, not an authenticated admin workflow.
  • Header stripping or banner hiding only blinds scanners and defenders; it does not remove the vulnerable code path.
06 · Verification

Crowdsourced verification payload.

Run this on the target nginx host as a local audit, not from your scanner. Invoke it with sudo bash ./check_nginx_118956.sh; it needs permission to run nginx -V and nginx -T so it can inspect build flags and effective config. It returns VULNERABLE, PATCHED, or UNKNOWN and exits non-zero only for VULNERABLE.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check_nginx_118956.sh
# Assess exposure for Tenable plugin 118956 / nginx CVE-2018-16843, -16844, -16845
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

set -u

have_cmd() { command -v "$1" >/dev/null 2>&1; }

semver_ge() {
  [ "$1" = "$2" ] && return 0
  [ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | tail -n1)" = "$1" ]
}

semver_lt() {
  [ "$1" = "$2" ] && return 1
  [ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)" = "$1" ]
}

pkg_version_ge() {
  # Compare distro package versions if dpkg or rpm is available
  local a="$1" b="$2"
  if have_cmd dpkg --compare-versions 1 1 >/dev/null 2>&1; then
    dpkg --compare-versions "$a" ge "$b"
    return $?
  fi
  if have_cmd rpm; then
    rpm --quiet --eval '%{?dist}' >/dev/null 2>&1
    [ "$(printf '%s\n%s\n' "$a" "$b" | sort -V | tail -n1)" = "$a" ]
    return $?
  fi
  return 1
}

status="UNKNOWN"
reasons=()

if ! have_cmd nginx; then
  echo "UNKNOWN: nginx binary not found in PATH"
  exit 2
fi

nginx_v_raw="$(nginx -V 2>&1)"
nginx_t_raw="$(nginx -T 2>&1)"

nginx_ver="$(printf '%s' "$nginx_v_raw" | sed -n 's/^nginx version: nginx\/\([0-9][0-9.]*\).*$/\1/p' | head -n1)"
if [ -z "$nginx_ver" ]; then
  echo "UNKNOWN: unable to parse nginx version from 'nginx -V'"
  exit 2
fi

http2_compiled=0
mp4_compiled=0
printf '%s' "$nginx_v_raw" | grep -Eq 'http_v2_module' && http2_compiled=1
printf '%s' "$nginx_v_raw" | grep -Eq 'http_mp4_module' && mp4_compiled=1

http2_enabled=0
mp4_enabled=0
printf '%s\n' "$nginx_t_raw" | grep -Eiq '^[[:space:]]*listen[[:space:]].*http2([;[:space:]]|$)|^[[:space:]]*http2[[:space:]]+on[[:space:]]*;' && http2_enabled=1
printf '%s\n' "$nginx_t_raw" | grep -Eiq '^[[:space:]]*mp4[[:space:]]*;' && mp4_enabled=1

# Distro package version checks for common backports
pkg_name=""
pkg_ver=""
if have_cmd dpkg-query; then
  for p in nginx nginx-core nginx-full nginx-light nginx-extras nginx-common; do
    if dpkg-query -W -f='${Status} ${Version}\n' "$p" 2>/dev/null | grep -q '^install ok installed '; then
      pkg_name="$p"
      pkg_ver="$(dpkg-query -W -f='${Version}' "$p" 2>/dev/null)"
      break
    fi
  done
elif have_cmd rpm; then
  if rpm -q nginx >/dev/null 2>&1; then
    pkg_name="nginx"
    pkg_ver="$(rpm -q --qf '%{VERSION}-%{RELEASE}' nginx 2>/dev/null)"
  fi
fi

backport_patched=0
if [ -n "$pkg_ver" ]; then
  case "$pkg_ver" in
    *1.10.3-1+deb9u2*|*1.10.3-1+deb9u3*|*1.10.3-0ubuntu0.16.04.3*|*1.14.0-0ubuntu1.2*|*1.15.5-0ubuntu2.1*|*1.4.6-1ubuntu3.9*)
      backport_patched=1
      ;;
  esac
fi

http2_range_vuln=0
mp4_range_vuln=0

# HTTP/2 affected: 1.9.5-1.15.5; fixed in 1.14.1 and 1.15.6
if semver_ge "$nginx_ver" "1.9.5"; then
  if semver_lt "$nginx_ver" "1.14.1"; then
    http2_range_vuln=1
  elif semver_ge "$nginx_ver" "1.15.0" && semver_lt "$nginx_ver" "1.15.6"; then
    http2_range_vuln=1
  fi
fi

# MP4 affected: 1.1.3-1.15.5 and 1.0.7-1.0.15; fixed in 1.14.1 and 1.15.6
if semver_ge "$nginx_ver" "1.1.3"; then
  if semver_lt "$nginx_ver" "1.14.1"; then
    mp4_range_vuln=1
  elif semver_ge "$nginx_ver" "1.15.0" && semver_lt "$nginx_ver" "1.15.6"; then
    mp4_range_vuln=1
  fi
elif semver_ge "$nginx_ver" "1.0.7" && semver_lt "$nginx_ver" "1.0.16"; then
  mp4_range_vuln=1
fi

if [ "$backport_patched" -eq 1 ]; then
  echo "PATCHED: distro package backport detected (${pkg_name} ${pkg_ver})"
  exit 0
fi

http2_reachable=0
mp4_reachable=0
[ "$http2_range_vuln" -eq 1 ] && [ "$http2_compiled" -eq 1 ] && [ "$http2_enabled" -eq 1 ] && http2_reachable=1
[ "$mp4_range_vuln" -eq 1 ] && [ "$mp4_compiled" -eq 1 ] && [ "$mp4_enabled" -eq 1 ] && mp4_reachable=1

if [ "$http2_reachable" -eq 1 ] || [ "$mp4_reachable" -eq 1 ]; then
  echo "VULNERABLE: nginx ${nginx_ver} with reachable vulnerable path(s): HTTP2=${http2_reachable} MP4=${mp4_reachable}"
  echo "DETAIL: compiled_http2=${http2_compiled} enabled_http2=${http2_enabled} compiled_mp4=${mp4_compiled} enabled_mp4=${mp4_enabled}"
  exit 1
fi

# Not in vulnerable range, or features not reachable
if [ "$http2_range_vuln" -eq 0 ] && [ "$mp4_range_vuln" -eq 0 ]; then
  echo "PATCHED: nginx ${nginx_ver} is outside the upstream vulnerable ranges"
  exit 0
fi

if [ "$http2_range_vuln" -eq 1 ] || [ "$mp4_range_vuln" -eq 1 ]; then
  echo "PATCHED: nginx ${nginx_ver} is in a nominal vulnerable version range, but no reachable vulnerable config was found (HTTP2 compiled=${http2_compiled}, enabled=${http2_enabled}; MP4 compiled=${mp4_compiled}, enabled=${mp4_enabled})"
  exit 0
fi

echo "UNKNOWN: insufficient data to determine exposure"
exit 2
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning, do not mass-escalate this one just because a remote scanner saw an old nginx banner. First, validate which internet-facing hosts actually expose http2 or mp4; if they do, queue them for normal remediation and clean up unnecessary feature exposure during standard change windows. For a MEDIUM verdict there is no noisgate mitigation SLA — go straight to the 365-day remediation window; the noisgate remediation SLA is ≤365 days. If you discover a small set of revenue-critical edge nodes with live HTTP/2 exposure, patch those earlier as an availability-hardening task, but this is still not an emergency patch-everything event.

Sources

  1. Tenable Nessus Plugin 118956
  2. nginx security advisory for CVE-2018-16843 and CVE-2018-16844
  3. nginx security advisory for CVE-2018-16845
  4. nginx security advisories index
  5. NVD CVE-2018-16843
  6. NVD CVE-2018-16844
  7. NVD CVE-2018-16845
  8. Ubuntu USN-3812-1
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.