← Back to Feed CACHED · 2026-09-20 05:52:08 · CACHE_KEY CVE-2026-56860
CVE-2026-56860 · CWE-407 · Disclosed 2026-08-13

Previously

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

Like a zip bomb hidden in a breadcrumb trail — every '..' makes the parser re-walk the entire path

CVE-2026-56860 is a denial-of-service flaw in Go's standard library net/url package, specifically in the resolvePath function called by URL.Parse and URL.ResolveReference. When processing relative URL paths containing parent-directory (..) segments, the old implementation performed a full string conversion and buffer rewrite at every step, producing O(n²) time complexity and proportionally bloated memory allocations. An attacker who can feed a crafted URL with a long chain of .. segments into a Go service can spike CPU and heap usage on that process. Affected versions: Go < 1.25.13, Go 1.26.0 through 1.26.5, and Go 1.27.0-rc.1/rc.2. Fixed in Go 1.25.13, 1.26.6, and 1.27.0-rc.3.

The vendor's MEDIUM / 5.9 rating is directionally correct but slightly generous. The CVSS vector (AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H) already captures the high attack complexity and availability-only impact. In practice, several additional friction layers — HTTP URL-length ceilings, Go's goroutine-per-request model that isolates slow parsing to a single goroutine, the need for sustained concurrent malicious requests to actually degrade service, and the total absence of public PoC code or in-the-wild exploitation — all compound to make the real-world risk incrementally lower than what the raw CVSS communicates. A 4.8 better reflects the actual threat to a managed fleet.

"Go URL path parsing DoS via quadratic complexity — real but hard to weaponize at scale"
02 · The Attack Path

4 steps from start to impact.

STEP 01

Identify a Go-based network service

The attacker locates an HTTP API, reverse proxy, or microservice compiled with a vulnerable Go version (< 1.25.13, 1.26.0–1.26.5, 1.27.0-rc.1/rc.2). Fingerprinting Go services is possible via response headers (Server, TLS fingerprinting with JARM) or known product stacks (Caddy, Traefik, custom APIs). No tooling beyond standard recon is required.
Conditions required:
  • Target runs a Go binary compiled with a vulnerable Go toolchain
  • Service is network-reachable
Where this breaks in practice:
  • Go version is not typically disclosed in HTTP headers
  • Many Go services sit behind a CDN or reverse proxy that masks origin
Detection/coverage: Version detection via go version -m <binary> on the host. Network-side: TLS JARM fingerprinting can identify Go HTTP servers.
STEP 02

Craft a URL with deeply nested '..' segments

The attacker constructs a URL path containing hundreds or thousands of /../ segments, e.g. /a/../a/../a/../... repeated thousands of times. The goal is to maximize the number of iterations through resolvePath. The crafted URL must be a valid HTTP request that the Go service will parse. No specialized tooling is needed — curl or python requests suffices.
Conditions required:
  • Attacker can send arbitrary HTTP requests to the service
Where this breaks in practice:
  • Go's net/http server enforces MaxHeaderBytes (default 1 MB) which caps request-line length
  • Many WAFs and load balancers impose their own URL length limits (e.g. Cloudflare: 32 KB, AWS ALB: 8 KB)
  • URL normalization at the proxy layer may strip .. segments before they reach the Go process
Detection/coverage: WAF rules for excessive .. in URL path. Log analysis for abnormally long request URIs.
STEP 03

Trigger URL.Parse or URL.ResolveReference on untrusted input

The crafted URL must reach a code path in the target application that calls url.URL.Parse or url.URL.ResolveReference, which internally invokes resolvePath. The Go HTTP server's request parsing calls url.Parse on the request URL, so standard HTTP handlers may be affected. However, the specific resolvePath logic is invoked only when the path actually contains .. segments and requires resolution — not on every URL parse.
Conditions required:
  • Application processes the URL through a code path that invokes resolvePath
  • The .. segments survive any upstream normalization
Where this breaks in practice:
  • Go's HTTP server may clean/reject the path before handler dispatch depending on mux configuration
  • Applications using http.ServeMux get path.Clean applied, which may not trigger resolvePath
  • The CVSS AC:H reflects that not all Go HTTP services trigger the vulnerable code path
Detection/coverage: Use govulncheck to identify whether the application's call graph reaches the affected url.URL.Parse or url.URL.ResolveReference symbols.
STEP 04

Sustain concurrent requests to exhaust resources

A single malicious request will consume elevated CPU and memory in one goroutine but won't take down a well-provisioned Go service. The attacker must send many concurrent crafted requests to saturate CPU cores and exhaust heap memory. This moves the attack from 'annoying slow request' to 'service degradation.' Rate limiting, connection limits, and Go's runtime GC all work against the attacker.
Conditions required:
  • Attacker can sustain high-volume requests
  • No rate limiting or connection throttling in place
Where this breaks in practice:
  • Rate limiting at CDN/LB/WAF layer stops volume-based DoS
  • Go's goroutine scheduler and GC recover gracefully under moderate load
  • Kubernetes HPA or similar autoscaling can absorb burst CPU spikes
  • Standard DDoS mitigation (Cloudflare, AWS Shield) applies
Detection/coverage: Spike in goroutine count, heap allocation, and CPU per process. Prometheus metrics or runtime/pprof expose this.
03 · Intelligence Metadata

The supporting signals.

In-the-wild exploitationNone observed. Not listed in CISA KEV. No campaigns or threat actor usage reported as of 2026-09-20.
Proof of conceptNo public PoC. The Go issue #80494 was reported by *jitsu-net* on 2026-07-21 and handled under Go's security process. No exploit code has been published.
EPSS0.00518 (0.52%) — bottom quartile. The model rates exploitation probability as very low over the next 30 days.
KEV statusNot listed. No CISA KEV entry as of 2026-09-20.
CVSS vectorCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H — Network-accessible, high complexity, no privs needed, availability-only impact. The AC:H is the key limiter: not every Go service triggers resolvePath on untrusted input.
Affected versionsGo < 1.25.13, Go 1.26.0 through 1.26.5, Go 1.27.0-rc.1 through 1.27.0-rc.2
Fixed versionsGo 1.25.13, 1.26.6, 1.27.0-rc.3+. Distro backports: RHSA-2026:65886 (RHEL), RHSA-2026:67975, RHSA-2026:68527.
Affected symbolsurl.URL.Parse, url.URL.ResolveReference → internal resolvePath function
Scanning / exposureNo Shodan/GreyNoise/Censys data specific to this CVE. Go HTTP services are identifiable via JARM TLS fingerprinting but the vulnerability requires application-level analysis (govulncheck), not network scanning.
Reporterjitsu-net via Go security process. Tracked as GO-2026-6218, GHSA-25mv-j2qr-v5jq.
04 · The Call

Final Verdict
= UNCHANGED to MEDIUM (4.8/10)

Why this verdict

  • No exploitation evidence or PoC: Zero in-the-wild activity, no KEV listing, no public exploit code. EPSS at 0.52% puts this in the bottom quartile. There is nothing to chase right now.
  • AC:H is real friction, not theoretical: The resolvePath code path is only invoked when URL paths contain .. segments *and* pass through URL.Parse or URL.ResolveReference. Go's standard http.ServeMux applies path.Clean before dispatch, and many reverse proxies normalize paths upstream, meaning the vulnerable code path is not universally reachable on every Go HTTP endpoint.
  • Availability-only impact with natural throttling: Even when triggered, the quadratic blowup is confined to a single goroutine. Go's concurrency model, runtime GC, and typical deployment patterns (load balancer, rate limiting, autoscaling) all limit the blast radius of a single crafted request. Sustained concurrent volume is required for service-level impact, which crosses into generic DDoS territory where existing mitigations apply.
  • URL length ceilings cap the payload: Go's net/http enforces a default MaxHeaderBytes of 1 MB, and upstream proxies (Cloudflare 32 KB, AWS ALB 8 KB) impose tighter limits. The quadratic factor is bounded by input length, so the worst-case CPU spike is architecturally capped.
  • Role multiplier: Go's net/url is used in high-value components — Kubernetes API server, Docker/containerd, HashiCorp Vault, Traefik, Caddy, Prometheus. The chain *can* succeed against these if an attacker reaches them with crafted URLs. However, the outcome is always service-level DoS (one process, recoverable), never domain takeover, fleet compromise, data exfiltration, or supply-chain pivot. Kubernetes API servers require authentication for most endpoints; Vault requires tokens; network proxies are typically behind DDoS mitigation. The blast radius is host-level at worst, goroutine-level typically. This does not meet the HIGH floor threshold because no high-value role outcome reaches 'domain takeover / fleet compromise / mass data egress / supply-chain pivot.'

Why not higher?

The vulnerability produces availability impact only — no path to code execution, privilege escalation, data disclosure, or lateral movement. The outcome ceiling is transient service degradation on a single Go process, not domain compromise or fleet-scale impact. The attack requires sustained concurrent malicious requests, making it operationally equivalent to a generic application-layer DDoS rather than a precise exploit chain. No PoC or exploitation evidence exists to justify urgency.

Why not lower?

Go is the dominant language for cloud-native infrastructure. The net/url package is nearly universal in Go codebases, and while the specific resolvePath trigger requires .. segments, the sheer number of Go services processing untrusted URLs means the addressable attack surface is non-trivial. The flaw is unauthenticated and network-reachable, and a determined attacker targeting a specific high-value Go service (e.g., an unprotected API gateway) could cause meaningful disruption. Dropping below MEDIUM would understate the risk to unshielded deployments.

05 · Compensating Control

What to do — in priority order.

  1. Run govulncheck across your Go module inventory — Use govulncheck ./... in each Go module to determine whether your application's call graph actually reaches the vulnerable url.URL.Parse or url.URL.ResolveReference symbols. If govulncheck reports no reachable usage, the binary is not exploitable regardless of Go version. This triage step eliminates false positives and focuses patching effort. No mitigation SLA applies for MEDIUM — go straight to the 365-day remediation window.
  2. Enforce URL length limits at the edge — Configure your reverse proxy, WAF, or load balancer to reject request URLs exceeding a reasonable length (e.g. 8 KB). This caps the quadratic blowup factor and neutralizes the DoS potential. Most production deployments already have this in place. Apply within the 365-day remediation window.
  3. Normalize paths at the proxy layer — Enable path normalization (resolve .. segments) at your reverse proxy (nginx merge_slashes, Envoy path normalization, Cloudflare URL rewriting). This strips the malicious .. chains before they reach Go, eliminating the trigger entirely.
  4. Rebuild and redeploy with Go ≥ 1.25.13 / 1.26.6 — The definitive fix is recompiling your Go binaries with a patched Go toolchain. Prioritize services that are internet-facing and process untrusted URLs. Target completion within the noisgate 365-day remediation SLA for MEDIUM severity.
  5. Enable rate limiting on URL-processing endpoints — Apply per-client rate limiting at the application or proxy level to prevent the sustained concurrent requests needed to escalate a single-goroutine slowdown into service-level DoS.
What doesn't work
  • Input validation on .. in application code — by the time your handler sees the request, Go's HTTP server has already parsed the URL via url.Parse, which is where the vulnerability triggers. Validating the path in your handler is too late.
  • Upgrading only the Go binary without recompiling — Go statically links the standard library. You must recompile your application with the patched Go toolchain; simply updating the go command on the host does nothing for already-deployed binaries.
  • Generic network-level DDoS protection alone — while DDoS mitigation helps with the volume component, a single well-crafted request with a long .. chain can still cause a CPU spike in one goroutine. The algorithmic fix in the Go runtime is the only complete remediation.
06 · Verification

Crowdsourced verification payload.

Run this script on any host where Go binaries are deployed. It checks the Go toolchain version and optionally scans specified binaries for their embedded Go version. Requires go in PATH for toolchain check, or pass binary paths as arguments. No elevated privileges needed. Example: bash check_cve_2026_56860.sh /usr/local/bin/myservice /usr/bin/kubectl

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check_cve_2026_56860.sh — Detect Go net/url quadratic path resolution DoS
# CVE-2026-56860 | GO-2026-6218
# Affected: Go < 1.25.13, Go 1.26.0-1.26.5, Go 1.27.0-rc.1/rc.2
# Fixed:    Go 1.25.13+, Go 1.26.6+, Go 1.27.0-rc.3+
# Usage:    bash check_cve_2026_56860.sh [binary1 binary2 ...]
# Output:   VULNERABLE / PATCHED / UNKNOWN

set -euo pipefail

VULNERABLE=0
PATCHED=0
UNKNOWN=0

check_version() {
  local label="$1"
  local ver="$2"
  # Strip 'go' prefix if present
  ver="${ver#go}"
  # Extract major.minor.patch
  local major minor patch
  IFS='.' read -r major minor patch <<< "$(echo "$ver" | sed 's/-.*//; s/rc.*//')"
  patch="${patch:-0}"
  local rc=""
  if [[ "$ver" == *"-rc."* ]]; then
    rc="$(echo "$ver" | grep -oP 'rc\.\K[0-9]+')"
  elif [[ "$ver" == *"rc"* ]]; then
    rc="$(echo "$ver" | grep -oP 'rc\K[0-9]+')"
  fi

  local result="UNKNOWN"

  if [[ "$major" -eq 1 ]]; then
    if [[ "$minor" -le 24 ]]; then
      # Go 1.24 and earlier — not in affected range per advisory (affected starts 1.25.0)
      result="PATCHED"  # Not in affected version range
    elif [[ "$minor" -eq 25 ]]; then
      if [[ "$patch" -ge 13 ]]; then
        result="PATCHED"
      else
        result="VULNERABLE"
      fi
    elif [[ "$minor" -eq 26 ]]; then
      if [[ "$patch" -ge 6 ]]; then
        result="PATCHED"
      else
        result="VULNERABLE"
      fi
    elif [[ "$minor" -eq 27 ]]; then
      if [[ -n "$rc" ]]; then
        if [[ "$rc" -ge 3 ]]; then
          result="PATCHED"
        else
          result="VULNERABLE"
        fi
      elif [[ "$patch" -ge 0 ]]; then
        result="PATCHED"  # 1.27.0 release or later
      fi
    elif [[ "$minor" -gt 27 ]]; then
      result="PATCHED"
    fi
  fi

  echo "[$result] $label: go$ver"
  case "$result" in
    VULNERABLE) VULNERABLE=$((VULNERABLE + 1)) ;;
    PATCHED)    PATCHED=$((PATCHED + 1)) ;;
    *)          UNKNOWN=$((UNKNOWN + 1)) ;;
  esac
}

# Check installed Go toolchain
if command -v go &>/dev/null; then
  toolchain_ver="$(go version | awk '{print $3}')"
  check_version "Go toolchain" "$toolchain_ver"
else
  echo "[INFO] Go toolchain not found in PATH"
fi

# Check specified binaries
for bin in "$@"; do
  if [[ ! -f "$bin" ]]; then
    echo "[UNKNOWN] $bin: file not found"
    UNKNOWN=$((UNKNOWN + 1))
    continue
  fi
  bin_ver="$(go version -m "$bin" 2>/dev/null | head -1 | awk '{print $2}' || true)"
  if [[ -z "$bin_ver" ]]; then
    echo "[UNKNOWN] $bin: not a Go binary or version unreadable"
    UNKNOWN=$((UNKNOWN + 1))
    continue
  fi
  check_version "$bin" "$bin_ver"
done

# Summary
echo ""
echo "=== CVE-2026-56860 Scan Summary ==="
echo "VULNERABLE: $VULNERABLE | PATCHED: $PATCHED | UNKNOWN: $UNKNOWN"

if [[ $VULNERABLE -gt 0 ]]; then
  echo "VULNERABLE"
  exit 1
elif [[ $UNKNOWN -gt 0 && $PATCHED -eq 0 ]]; then
  echo "UNKNOWN"
  exit 2
else
  echo "PATCHED"
  exit 0
fi
07 · Sources

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.