Skip to main content
Vulnerability Database/CVE-2026-86043

CVE-2026-86043: Skipper HTTP Router Auth Bypass Vulnerability

CVE-2026-86043 is an authentication bypass flaw in Skipper HTTP router that allows oversized request authorization after body truncation. This post explains its technical details, affected versions, impact, and mitigation steps.

Published:

CVE-2026-86043 Overview

Skipper is an HTTP router and reverse proxy for service composition maintained by Zalando. Versions prior to 0.27.37 contain an authorization bypass in the opaAuthorizeRequestWithBody filter. The filter authorizes oversized requests after Skipper truncates the body presented to Open Policy Agent (OPA). The input.truncated_body signal is derived from Content-Length rather than the actual read result. Policies that trust this signal can approve requests based on a truncated prefix, then forward the full oversized body to the protected upstream service. This residual issue is distinct from CVE-2026-50197 and is classified as [CWE-863] Incorrect Authorization.

Critical Impact

A remote unauthenticated attacker can bypass body-inspecting OPA policies using HTTP/1.1 Transfer-Encoding: chunked or HTTP/2 requests without Content-Length, delivering full oversized payloads to upstream services.

Affected Products

  • Zalando Skipper prior to version 0.27.37
  • Deployments using the opaAuthorizeRequestWithBody filter
  • OPA policies relying on the input.truncated_body signal for authorization decisions

Discovery Timeline

  • 2026-09-16 - CVE-2026-86043 published to NVD
  • 2026-09-16 - Last updated in NVD database

Technical Details for CVE-2026-86043

Vulnerability Analysis

The flaw resides in Skipper's Open Policy Agent integration for request authorization. When the opaAuthorizeRequestWithBody filter processes a request, ExtractHttpBodyOptionally in filters/openpolicyagent/openpolicyagent.go truncates request bodies at maxBodyBytes. The adapter in filters/openpolicyagent/internal/envoy/skipperadapter.go then copies request headers to the OPA CheckRequest without adjusting Content-Length to reflect the truncation.

The input.truncated_body value passed to OPA is computed from the original Content-Length header. For requests using Transfer-Encoding: chunked under HTTP/1.1 or HTTP/2 requests that omit Content-Length, the header-derived truncation indicator cannot detect that the actual read was cut short. OPA policies following the prior CVE-2026-50197 mitigation permit requests where input.truncated_body equals false, trusting a signal that does not match reality.

Root Cause

The root cause is a mismatch between the truncation signal source and the actual body read outcome. The signal is derived from a request header value rather than the byte count returned by the body reader. Chunked and length-less requests defeat header-based accounting entirely.

Attack Vector

An attacker sends an oversized HTTP request using Transfer-Encoding: chunked or an HTTP/2 request without Content-Length. OPA evaluates only the truncated prefix, which satisfies the policy. Skipper then proxies the complete oversized body to the upstream service, bypassing the intended input-size and content constraints.

go
// Patch: filters/openpolicyagent/internal/envoy/skipperadapter.go
// The AdaptToExtAuthRequest function now accepts an explicit bodyTruncated
// parameter derived from the actual read result rather than Content-Length.
-func AdaptToExtAuthRequest(req *http.Request, metadata *ext_authz_v3_core.Metadata, contextExtensions map[string]string, rawBody []byte) (*ext_authz_v3.CheckRequest, error) {
+func AdaptToExtAuthRequest(req *http.Request, metadata *ext_authz_v3_core.Metadata, contextExtensions map[string]string, rawBody []byte, bodyTruncated bool) (*ext_authz_v3.CheckRequest, error) {
 	if err := validateURLForInvalidUTF8(req.URL); err != nil {
 		return nil, fmt.Errorf("invalid url: %w", err)
 	}

// Patch: filters/openpolicyagent/opaauthorizerequest/opaauthorizerequest.go
// ExtractHttpBodyOptionally now returns an authoritative bodyTruncated flag.
 	var rawBodyBytes []byte
+	var bodyTruncated bool
 	if f.bodyParsing {
-		body, rawBodyBytes, finalizer, err = f.opa.ExtractHttpBodyOptionally(req)
+		body, rawBodyBytes, bodyTruncated, finalizer, err = f.opa.ExtractHttpBodyOptionally(req)
 		defer finalizer()

Source: GitHub Commit 2cfceab

Detection Methods for CVE-2026-86043

Indicators of Compromise

  • Incoming requests with Transfer-Encoding: chunked combined with body sizes exceeding the configured OPA maxBodyBytes limit.
  • HTTP/2 requests targeting opaAuthorizeRequestWithBody-protected routes that omit Content-Length.
  • Upstream services receiving payload sizes larger than the OPA-evaluated body length recorded in Skipper access logs.

Detection Strategies

  • Compare byte counts between Skipper access logs and upstream service request logs to identify size discrepancies on OPA-authorized routes.
  • Alert on OPA decision logs where input.truncated_body is false but the raw body size at the upstream exceeds maxBodyBytes.
  • Deploy a middleware or WAF rule to reject or flag chunked requests exceeding a size threshold on authorization-protected endpoints.

Monitoring Recommendations

  • Enable OPA decision logging and correlate authorization outcomes with upstream request sizes.
  • Track Skipper filter metrics for opaAuthorizeRequestWithBody invocation counts alongside truncation events.
  • Monitor upstream services for anomalous large-payload requests originating from Skipper after successful OPA authorization.

How to Mitigate CVE-2026-86043

Immediate Actions Required

  • Upgrade Skipper to version 0.27.37 or later, which passes an authoritative bodyTruncated value from the read result to OPA.
  • Audit all OPA policies that reference input.truncated_body to confirm they deny requests when the signal indicates truncation.
  • Enforce request size limits at an upstream layer such as a WAF or load balancer to reduce reliance on the OPA-derived signal.

Patch Information

The fix is available in Skipper release v0.27.35 and the advisory notes remediation in version 0.27.37. See the GHSA-5gpm-rgj3-9q76 advisory and the source code for v0.27.35. The patch introduces an authoritative bodyTruncated boolean returned from ExtractHttpBodyOptionally and propagated into AdaptToExtAuthRequest, so OPA receives a truncation signal derived from the actual read length rather than Content-Length.

Workarounds

  • Disable bodyParsing on the opaAuthorizeRequestWithBody filter for routes that do not require body inspection.
  • Reject Transfer-Encoding: chunked requests on authorization-protected routes at an ingress layer until the upgrade is applied.
  • Enforce a strict upstream request-size limit lower than Skipper's maxBodyBytes so oversized bodies are rejected before reaching the protected service.
bash
# Upgrade Skipper to the fixed version
go install github.com/zalando/skipper/cmd/skipper@v0.27.37

# Verify the running version
skipper -version

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.