← Back to Feed CACHED · 2026-09-08 13:32:11 · CACHE_KEY CVE-2026-75021
CVE-2026-75021 · CWE-1327 · Disclosed 2026-09-08

fastify-cli starts the Node.js Inspector when a debug flag is used

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

Like a locksmith who cuts a deadbolt key but hands it to the wrong door — fastify-cli promises to restrict the inspector and then binds it wide open

CVE-2026-75021 affects fastify-cli, the official CLI runner for the Fastify Node.js web framework. When a developer starts their app with the --debug (or -d) flag and explicitly provides a bind address (e.g., --debug-host 127.0.0.1), the tool silently ignores the user-supplied host under certain conditions — particularly inside Docker or Kubernetes — and binds the Node.js V8 Inspector to 0.0.0.0 (all interfaces). The V8 Inspector protocol is unauthenticated by design; anyone who can reach the debug port (default 9320 in fastify-cli) gets full Runtime.evaluate access, which means arbitrary code execution as the Node.js process user. Affected versions appear to be all fastify-cli releases that include the debug mode feature (introduced via PR #202), up to and including versions prior to the patch disclosed on September 7, 2026. The latest npm release is 7.4.1 on the v7 line and 8.0.0 on the v8 line.

The vendor rates this HIGH 8.1 with CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H, and on paper that vector is technically accurate — if the inspector is exposed, it's unauthenticated RCE over the network. But the vendor score overstates the real-world risk for enterprise shops because it doesn't price in the most important friction: debug mode must be deliberately enabled. This is not a default behavior; it requires passing -d or --debug at startup. In any environment following basic operational hygiene, debug flags are stripped before production deployment. The population of real-world hosts running fastify-cli in debug mode on a reachable network is vanishingly small. The HIGH rating makes sense as a ceiling for developers actively debugging in containerized environments, but as a fleet-wide priority signal it misleads — this is a MEDIUM-severity issue for most organizations.

"Debug-mode-only vuln in a dev CLI — not a production threat for most shops"
02 · The Attack Path

4 steps from start to impact.

STEP 01

Debug mode is explicitly enabled

An operator or developer starts the Fastify application using fastify-cli with the -d/--debug flag. This is a deliberate opt-in action; the inspector is not enabled by default. The user may also pass --debug-host 127.0.0.1 attempting to restrict the listener.
Conditions required:
  • Operator explicitly passes -d or --debug flag at startup
  • fastify-cli is installed and used as the process runner
Where this breaks in practice:
  • Debug mode is a development feature — CI/CD pipelines and production Dockerfiles should never include it
  • Most deployment automation (Helm charts, systemd units, PM2 configs) does not inject debug flags
Detection/coverage: Port scanning for 9320/tcp or the configured debug port; nmap -sV -p 9320 will identify the V8 inspector protocol header.
STEP 02

Inspector binds to 0.0.0.0 despite explicit host

Due to the bug in fastify-cli's start.js, the user's --debug-host value is not properly propagated to opts.debugHost. The nullish coalescing fallback (??) then triggers the Docker/Kubernetes detection path, which sets the bind address to 0.0.0.0. The inspector is now listening on all network interfaces instead of the intended restricted address.
Conditions required:
  • Running inside a Docker container or Kubernetes pod (triggers the fallback path)
  • Or: opts.debugHost is falsy due to the argument parsing bug
Where this breaks in practice:
  • Outside of containers, the fallback is undefined, which Node.js maps to 127.0.0.1 — so bare-metal dev workstations are largely unaffected
  • K8s network policies or Docker network isolation may still block cross-pod/cross-container access to the port
STEP 03

Attacker discovers the open inspector port

The attacker scans the target network or K8s pod network and finds port 9320 (or the configured debug port) responding with the V8 inspector WebSocket metadata endpoint at /json. This endpoint returns the WebSocket debugger URL without any authentication challenge.
Conditions required:
  • Network path from attacker to the debug port (no firewall, no K8s NetworkPolicy blocking it)
  • Attacker is on the same network segment, pod network, or has a foothold that can reach the port
Where this breaks in practice:
  • Default K8s NetworkPolicies in hardened clusters deny cross-namespace traffic
  • Most enterprise firewalls block arbitrary high ports from external access
  • Inspector port is non-standard (9320 vs the well-known 9229) which reduces drive-by scanning hits
Detection/coverage: GreyNoise or honeypot data for port 9320 scanning; internal IDS rules for V8 inspector protocol handshake patterns.
STEP 04

RCE via V8 Inspector protocol

The attacker connects to the WebSocket debugger URL and sends a Runtime.evaluate command with arbitrary JavaScript. This executes in the context of the Node.js process, giving the attacker the ability to spawn child processes, read/write files, and exfiltrate data — all as the process user. Tools like pwnnode, Chrome DevTools, or a simple WebSocket client suffice.
Conditions required:
  • Successful WebSocket connection to the inspector endpoint
Where this breaks in practice:
  • If the Node.js process runs as a non-root user in a read-only container, lateral movement is constrained
  • Container security profiles (seccomp, AppArmor) may limit child_process spawning
Detection/coverage: Runtime application self-protection (RASP) or eBPF-based tools can detect unexpected child_process.exec calls; audit logs for outbound connections from the Node.js process.
03 · Intelligence Metadata

The supporting signals.

In-the-wild exploitationNo known exploitation. Not listed on CISA KEV. No campaigns or threat actor usage reported as of 2026-09-08.
Proof-of-conceptNo public PoC specific to this CVE. However, generic V8 Inspector exploitation is well-documented — HackTricks and the pwnnode tool provide turnkey RCE once the inspector is reachable.
EPSSNot yet scored (CVE disclosed 2026-09-08, EPSS data typically lags 1–7 days). Expected to be low given the opt-in prerequisite.
KEV statusNot listed. No CISA KEV entry as of 2026-09-08.
CVSS vectorCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H — 8.1 HIGH. The AC:H reflects the need for debug mode to be active, but does not fully capture the opt-in nature of the feature.
Affected versionsAll fastify-cli versions with debug mode support (introduced ~2019 via PR #202). Likely affects versions through 7.x and 8.x prior to the patch.
Fixed versionsPatch disclosed via GHSA-88v4-3ph7-r88m on 2026-09-07. Exact patched version not yet confirmed in npm registry — check for releases ≥7.4.2 or ≥8.0.1.
Scanning / exposure dataNo Shodan or GreyNoise data specific to fastify-cli inspector port (9320). Generic V8 inspector port 9229 shows ~2,500 hosts globally on Shodan — most are honeypots or misconfigured dev instances.
Installed basefastify-cli: ~65K weekly npm downloads. Modest footprint. The Fastify framework itself is ~8.5M/week, but most users run Fastify directly without the CLI wrapper.
ReporterMatteo Collina (mcollina) — Fastify core maintainer and Node.js TSC member. Self-reported by the project.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to MEDIUM (5.3/10)

The single most decisive factor is that debug mode is an explicit opt-in flag (-d/--debug) that should never be present in production deployments, reducing the reachable population to near-zero for enterprise fleets. The resulting RCE impact is real but gated behind a development-only configuration that standard deployment pipelines strip out.

HIGH Vulnerability mechanism (bind address ignored → inspector exposed)
MEDIUM Exact affected and patched version ranges (advisory detail incomplete)
HIGH Real-world exploitability assessment (debug mode opt-in is the key gate)

Why this verdict

  • Debug mode is opt-in: The -d/--debug flag must be explicitly passed at startup. No production deployment template, Helm chart, or PM2 ecosystem file should include this flag. This is the dominant friction that collapses the reachable attack surface.
  • Container-path specificity: The bind-to-0.0.0.0 fallback triggers specifically when Docker/K8s is detected AND the user's host flag is improperly parsed. Bare-metal and VM-based dev environments default to localhost, limiting exposure further.
  • Modest installed base: At ~65K weekly downloads, fastify-cli is a recognized but niche tool. The vast majority of Fastify apps (8.5M downloads/week) are run directly via node or process managers, not through the CLI.
  • Role multiplier: fastify-cli runs Node.js web applications. (a) *Low-value role* (dev workstation): most common, debug mode is expected here but localhost binding usually holds. (b) *Typical role* (staging/app server): debug flags should be absent. (c) *High-value role* (CI/CD runner): theoretically possible but debug mode on CI is abnormal — build scripts use fastify generate or npm test, not fastify start -d. fastify-cli is not canonically a high-value-role component; <1% of installs would occupy CI/CD or identity-tier roles. The blast radius floor does not trigger.
  • No exploitation in the wild: No KEV listing, no campaigns, no public PoC tailored to this specific CVE. Generic inspector exploitation tooling exists but requires the rare precondition of debug mode being active.

Why not higher?

Promoting to HIGH would require evidence that a meaningful fraction of fastify-cli deployments run with debug mode in production or in high-value roles. The ~65K weekly download base is predominantly developers using the CLI locally; the intersection of 'debug mode active' + 'network-reachable inspector port' + 'production or high-value host' is negligibly small. The vendor's 8.1 score is technically valid for the *specific scenario* but dramatically overweights the general-population risk.

Why not lower?

Dropping to LOW would undercount the impact *when the bug fires*. If a developer in a containerized environment explicitly sets a bind address for security and the tool silently ignores it, the resulting exposure is unauthenticated RCE — a genuine betrayal of the user's security intent. The CWE-1327 (binding to unrestricted IP) is a real defect, not a theoretical concern, and the V8 inspector attack path is trivially weaponizable with off-the-shelf tooling once the port is reachable.

05 · Compensating Control

What to do — in priority order.

  1. Audit all startup scripts and Dockerfiles for debug flags — Search your codebase and container image build pipelines for -d, --debug, --debug-port, and --debug-host flags passed to fastify start. Remove them from any non-local-dev context. This is the single highest-leverage action since it eliminates the precondition entirely. No mitigation SLA applies for MEDIUM — go straight to the 365-day remediation window.
  2. Block inspector ports at the network layer — Add firewall rules or K8s NetworkPolicies to deny inbound traffic on port 9320 (and 9229) from any source outside localhost. This neutralizes the exposure even if debug mode is accidentally left on.
  3. Use container seccomp/AppArmor profiles to restrict child_process — If the inspector is somehow reached, a restrictive seccomp profile that blocks execve and fork will prevent the attacker from spawning shells or lateral-movement tools.
  4. Upgrade fastify-cli to the patched version — Once the patched version is confirmed in npm (expected ≥7.4.2 or ≥8.0.1), upgrade via npm update fastify-cli. This fixes the root cause. Target completion within the 365-day noisgate remediation SLA for MEDIUM.
What doesn't work
  • WAF or reverse proxy in front of the Fastify app — The inspector runs on a separate port (9320) from the HTTP application port. WAF rules on the app port do not intercept inspector protocol traffic.
  • Node.js --inspect host restrictions — The bug is in fastify-cli's argument handling, not in Node.js itself. Passing --inspect=127.0.0.1:9229 to Node directly would work, but fastify-cli's debug mode uses inspector.open() programmatically, bypassing Node's CLI flag parsing.
  • npm audit — As of 2026-09-08, npm audit may not yet reflect this advisory. Don't rely on it as sole detection for the next few days.
06 · Verification

Crowdsourced verification payload.

Run this on any host where fastify-cli is installed, as any user with read access to node_modules. Example: bash check_cve_2026_75021.sh /path/to/project. No elevated privileges required.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check_cve_2026_75021.sh — Detect fastify-cli versions vulnerable to CVE-2026-75021
# Usage: bash check_cve_2026_75021.sh [project_dir]
# Exit codes: 0 = PATCHED/NOT_AFFECTED, 1 = VULNERABLE, 2 = UNKNOWN

set -euo pipefail

PROJECT_DIR="${1:-.}"
CLI_PKG="$PROJECT_DIR/node_modules/fastify-cli/package.json"

if [ ! -f "$CLI_PKG" ]; then
  echo "UNKNOWN — fastify-cli not found in $PROJECT_DIR/node_modules"
  exit 2
fi

VERSION=$(grep '"version"' "$CLI_PKG" | head -1 | sed 's/.*"version": *"\([^"]*\)".*/\1/')
echo "Found fastify-cli version: $VERSION"

# Check if debug mode code contains the vulnerable pattern
START_JS="$PROJECT_DIR/node_modules/fastify-cli/start.js"
if [ ! -f "$START_JS" ]; then
  echo "UNKNOWN — start.js not found, cannot inspect code"
  exit 2
fi

# Look for the vulnerable pattern: inspector.open with Docker/K8s fallback
# that doesn't properly respect the user-supplied host
if grep -q 'inspector.*open' "$START_JS" 2>/dev/null; then
  # Check if the fix is applied (proper host passthrough)
  if grep -q 'debugHost.*??.*isDocker\|debugHost.*??.*isKubernetes' "$START_JS" 2>/dev/null; then
    echo "VULNERABLE — fastify-cli $VERSION contains the flawed inspector bind logic (CVE-2026-75021)"
    echo "The --debug-host flag may be silently ignored in container environments."
    exit 1
  else
    echo "PATCHED — fastify-cli $VERSION does not contain the vulnerable fallback pattern"
    exit 0
  fi
else
  echo "PATCHED — fastify-cli $VERSION does not use inspector.open (debug mode may not be present)"
  exit 0
fi
07 · Bottom Line

If you remember one thing.

TL;DR
This is a MEDIUM on the noisgate scale — a real bug but one gated behind a development-only flag that has no business running in production. There is no noisgate mitigation SLA for MEDIUM; go straight to the 365-day noisgate remediation SLA. Concretely: by end of this week, audit your Dockerfiles and CI configs for any fastify-cli debug flags and remove them — that takes 15 minutes and eliminates the precondition. Then, within your normal dependency update cycle, upgrade fastify-cli to the patched version once it lands in npm (watch GHSA-88v4-3ph7-r88m). If you don't use fastify-cli at all — and most Fastify shops don't — this CVE requires zero action. Do not let the vendor's HIGH 8.1 label bump this ahead of your real CRITICAL and HIGH queue items.

Sources

  1. GitHub Advisory — GHSA-88v4-3ph7-r88m
  2. fastify-cli debug mode PR #202
  3. CWE-1327: Binding to an Unrestricted IP Address
  4. Node.js Inspector security documentation
  5. HackTricks — Node Inspector / CEF debug abuse
  6. fastify-cli on npm
  7. Invicti — Node.js Inspector Unauthorized Access
  8. fastify-cli on Snyk
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.