Every CVE Search/ Get API key

CVE-2026-86043

Skipper: OPA body-authz bypass: truncated_body mitigation fails open on chunked/HTTP-2 (incomplete fix CVE-2026-50197)

7.5 HighFix available

Skipper is an HTTP router and reverse proxy for service composition. Prior to version 0.27.37, the opaAuthorizeRequestWithBody filter can authorize an oversized request after Skipper truncates the body presented to Open Policy Agent because the input.truncated_body signal is derived from Content-Length rather than the actual read result. In filters/openpolicyagent/openpolicyagent.go, ExtractHttpBodyOptionally truncates bodies at maxBodyBytes, while filters/openpolicyagent/internal/envoy/skipperadapter.go copies the request headers without adding a Content-Length value that reflects the truncation. For an HTTP/1.1 request using Transfer-Encoding: chunked or an HTTP/2 request without Content-Length, a body-inspecting policy that follows the prior mitigation and permits input.truncated_body equal to false can evaluate only the truncated prefix, allow the request, and then forward the full oversized body to the protected upstream. This residual issue is distinct from CVE-2026-50197. This issue is fixed in version 0.27.37.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
None
Integrity
High
Availability
None

Exploit likelihood

0.45%Unchanged since Sep 17, 2026
90%50%10%1%

What each source reports

CVE List Score used 7.5

Skipper: OPA body-authz bypass: truncated_body mitigation fails open on chunked/HTTP-2 (incomplete fix CVE-2026-50197)

Skipper is an HTTP router and reverse proxy for service composition. Prior to version 0.27.37, the opaAuthorizeRequestWithBody filter can authorize an oversized request after Skipper truncates the body presented to Open Policy Agent because the input.truncated_body signal is derived from Content-Length rather than the actual read result. In filters/openpolicyagent/openpolicyagent.go, ExtractHttpBodyOptionally truncates bodies at maxBodyBytes, while filters/openpolicyagent/internal/envoy/skipperadapter.go copies the request headers without adding a Content-Length value that reflects the truncation. For an HTTP/1.1 request using Transfer-Encoding: chunked or an HTTP/2 request without Content-Length, a body-inspecting policy that follows the prior mitigation and permits input.truncated_body equal to false can evaluate only the truncated prefix, allow the request, and then forward the full oversized body to the protected upstream. This residual issue is distinct from CVE-2026-50197. This issue is fixed in version 0.27.37.

Record
CVE-2026-86043
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N
Weakness
CWE-863
Updated
2026-11-02
EUVDEUVD-2026-81002 7.5

Skipper is an HTTP router and reverse proxy for service composition. Prior to version 0.27.37, the opaAuthorizeRequestWithBody filter can authorize an oversized request after Skipper truncates the body presented to Open Policy Agent because the input.truncated_body signal is derived from Content-Length rather than the actual read result. In filters/openpolicyagent/openpolicyagent.go, ExtractHttpBodyOptionally truncates bodies at maxBodyBytes, while filters/openpolicyagent/internal/envoy/skipperadapter.go copies the request headers without adding a Content-Length value that reflects the truncation. For an HTTP/1.1 request using Transfer-Encoding: chunked or an HTTP/2 request without Content-Length, a body-inspecting policy that follows the prior mitigation and permits input.truncated_body equal to false can evaluate only the truncated prefix, allow the request, and then forward the full oversized body to the protected upstream. This residual issue is distinct from CVE-2026-50197. This issue is fixed in version 0.27.37.

Record
EUVD-2026-81002
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-5gpm-rgj3-9q76 7.5

Skipper has OPA body-authz bypass: truncated_body mitigation fails open on chunked/HTTP-2 (incomplete fix GHSA-8qqm-fp2q-v734)

  • Affected component: filters/openpolicyagent/openpolicyagent.go → ExtractHttpBodyOptionally; combined with github.com/open-policy-agent/opa-envoy-plugin envoyauth/request.go → getParsedBody / checkIfHTTPBodyTruncated. Filter: opaAuthorizeRequestWithBody.
  • Affected versions: <= 0.27.33 (current HEAD e7d7014c). The truncated_body mitigation was introduced/recommended in v0.27.26 (advisory GHSA-8qqm-fp2q-v734) and remains bypassable.
  • Fix chain being audited: CVE-2026-50197 (GHSA-659f-rgp5-w4wf, commit 3152f3b0) → GHSA-8qqm-fp2q-v734 (docs + code, commit 1be950cd #4126, v0.27.26). This finding is the third, still-open variant.

Summary

Skipper's opaAuthorizeRequestWithBody filter authorizes requests by handing the (bounded) request body to Open Policy Agent. When a body exceeds -open-policy-agent-max-request-body-size (default 1 MB), Skipper truncates it before OPA sees it. Advisory GHSA-8qqm-fp2q-v734 established that deny-on-presence / body-inspecting policies fail OPEN on oversized bodies, and its remediation instructs policy authors to guard on input.attributes.request.http.truncated_body (implemented as the top-level input.truncated_body):

default allow := false
allow if {
    input.truncated_body == false
    # ... body-based conditions
}

That mitigation is itself incomplete. The truncated_body flag is computed by the OPA envoy plugin only when a content-length header is present. A request sent with Transfer-Encoding: chunked (HTTP/1.1) or over HTTP/2 carries no content-length, so truncated_body is left false even though Skipper truncated the body. The mitigated policy therefore evaluates input.truncated_body == false as true and ALLOWS the request, while the full, un-inspected oversized payload is forwarded to the upstream (Skipper's bufferedBodyReader streams the buffered prefix and then continues draining the original body).

The transport that defeats the mitigation — chunked / HTTP-2 without Content-Length — is the exact transport class the original CVE-2026-50197 was about; the GHSA-8qqm fix closed the declared-Content-Length variant and its positive-control test only exercised small chunked bodies, never oversized chunked bodies.

Root cause

opa-envoy-plugin/envoyauth/request.go:

func getParsedBody(...) (any, bool, error) {
    if val, ok := headers["content-type"]; ok {
        if strings.Contains(val, "application/json") {
            ...
            if val, ok := headers["content-length"]; ok {          // <-- only path that sets truncation
                truncated, err := checkIfHTTPBodyTruncated(val, int64(len(body)))
                ...
                if truncated { return nil, true, nil }
            }
            ...
        } else if ... "application/x-www-form-urlencoded" { /* same content-length gate */ }
          else if ... "multipart/form-data"            { /* same content-length gate */ }
    }
    return data, false, nil     // <-- no content-length  ==> truncated_body = false
}

func checkIfHTTPBodyTruncated(contentLength string, bodyLength int64) (bool, error) {
    cl, _ := strconv.ParseInt(contentLength, 10, 64)
    if cl != -1 && cl > bodyLength { return true, nil }
    return false, nil
}

Truncation can only ever be signalled by comparing content-length against the received body length. With chunked/HTTP-2 there is no content-length, so the comparison is skipped and truncated_body is reported false. Skipper (ExtractHttpBodyOptionally) meanwhile does truncate the chunked body to maxBodyBytes (it sets expectedSize = maxBodyBytes when req.ContentLength < 0), producing the exact divergence: OPA is told "not truncated", but the body was truncated, and the backend receives the whole thing.

Reachability

  1. Deployment runs opaAuthorizeRequestWithBody with a body-inspecting policy that follows the GHSA-8qqm mitigation (`allow if…
Record
GHSA-5gpm-rgj3-9q76
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N
Weakness
CWE-863
Updated
2026-11-02
NVD 7.5

Skipper is an HTTP router and reverse proxy for service composition. Prior to version 0.27.37, the opaAuthorizeRequestWithBody filter can authorize an oversized request after Skipper truncates the body presented to Open Policy Agent because the input.truncated_body signal is derived from Content-Length rather than the actual read result. In filters/openpolicyagent/openpolicyagent.go, ExtractHttpBodyOptionally truncates bodies at maxBodyBytes, while filters/openpolicyagent/internal/envoy/skipperadapter.go copies the request headers without adding a Content-Length value that reflects the truncation. For an HTTP/1.1 request using Transfer-Encoding: chunked or an HTTP/2 request without Content-Length, a body-inspecting policy that follows the prior mitigation and permits input.truncated_body equal to false can evaluate only the truncated prefix, allow the request, and then forward the full oversized body to the protected upstream. This residual issue is distinct from CVE-2026-50197. This issue is fixed in version 0.27.37.

Record
CVE-2026-86043
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N
Weakness
CWE-863
Updated
2026-11-02
OSV 7.5

Skipper: OPA body-authz bypass: truncated_body mitigation fails open on chunked/HTTP-2 (incomplete fix CVE-2026-50197)

Skipper is an HTTP router and reverse proxy for service composition. Prior to version 0.27.37, the opaAuthorizeRequestWithBody filter can authorize an oversized request after Skipper truncates the body presented to Open Policy Agent because the input.truncated_body signal is derived from Content-Length rather than the actual read result. In filters/openpolicyagent/openpolicyagent.go, ExtractHttpBodyOptionally truncates bodies at maxBodyBytes, while filters/openpolicyagent/internal/envoy/skipperadapter.go copies the request headers without adding a Content-Length value that reflects the truncation. For an HTTP/1.1 request using Transfer-Encoding: chunked or an HTTP/2 request without Content-Length, a body-inspecting policy that follows the prior mitigation and permits input.truncated_body equal to false can evaluate only the truncated prefix, allow the request, and then forward the full oversized body to the protected upstream. This residual issue is distinct from CVE-2026-50197. This issue is fixed in version 0.27.37.

Record
CVE-2026-86043
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N
Weakness
CWE-863
Updated
2026-11-02
OSVGHSA-5gpm-rgj3-9q76 7.5

Skipper has OPA body-authz bypass: truncated_body mitigation fails open on chunked/HTTP-2 (incomplete fix GHSA-8qqm-fp2q-v734)

  • Affected component: filters/openpolicyagent/openpolicyagent.go → ExtractHttpBodyOptionally; combined with github.com/open-policy-agent/opa-envoy-plugin envoyauth/request.go → getParsedBody / checkIfHTTPBodyTruncated. Filter: opaAuthorizeRequestWithBody.
  • Affected versions: <= 0.27.33 (current HEAD e7d7014c). The truncated_body mitigation was introduced/recommended in v0.27.26 (advisory GHSA-8qqm-fp2q-v734) and remains bypassable.
  • Fix chain being audited: CVE-2026-50197 (GHSA-659f-rgp5-w4wf, commit 3152f3b0) → GHSA-8qqm-fp2q-v734 (docs + code, commit 1be950cd #4126, v0.27.26). This finding is the third, still-open variant.

Summary

Skipper's opaAuthorizeRequestWithBody filter authorizes requests by handing the (bounded) request body to Open Policy Agent. When a body exceeds -open-policy-agent-max-request-body-size (default 1 MB), Skipper truncates it before OPA sees it. Advisory GHSA-8qqm-fp2q-v734 established that deny-on-presence / body-inspecting policies fail OPEN on oversized bodies, and its remediation instructs policy authors to guard on input.attributes.request.http.truncated_body (implemented as the top-level input.truncated_body):

default allow := false
allow if {
    input.truncated_body == false
    # ... body-based conditions
}

That mitigation is itself incomplete. The truncated_body flag is computed by the OPA envoy plugin only when a content-length header is present. A request sent with Transfer-Encoding: chunked (HTTP/1.1) or over HTTP/2 carries no content-length, so truncated_body is left false even though Skipper truncated the body. The mitigated policy therefore evaluates input.truncated_body == false as true and ALLOWS the request, while the full, un-inspected oversized payload is forwarded to the upstream (Skipper's bufferedBodyReader streams the buffered prefix and then continues draining the original body).

The transport that defeats the mitigation — chunked / HTTP-2 without Content-Length — is the exact transport class the original CVE-2026-50197 was about; the GHSA-8qqm fix closed the declared-Content-Length variant and its positive-control test only exercised small chunked bodies, never oversized chunked bodies.

Root cause

opa-envoy-plugin/envoyauth/request.go:

func getParsedBody(...) (any, bool, error) {
    if val, ok := headers["content-type"]; ok {
        if strings.Contains(val, "application/json") {
            ...
            if val, ok := headers["content-length"]; ok {          // <-- only path that sets truncation
                truncated, err := checkIfHTTPBodyTruncated(val, int64(len(body)))
                ...
                if truncated { return nil, true, nil }
            }
            ...
        } else if ... "application/x-www-form-urlencoded" { /* same content-length gate */ }
          else if ... "multipart/form-data"            { /* same content-length gate */ }
    }
    return data, false, nil     // <-- no content-length  ==> truncated_body = false
}

func checkIfHTTPBodyTruncated(contentLength string, bodyLength int64) (bool, error) {
    cl, _ := strconv.ParseInt(contentLength, 10, 64)
    if cl != -1 && cl > bodyLength { return true, nil }
    return false, nil
}

Truncation can only ever be signalled by comparing content-length against the received body length. With chunked/HTTP-2 there is no content-length, so the comparison is skipped and truncated_body is reported false. Skipper (ExtractHttpBodyOptionally) meanwhile does truncate the chunked body to maxBodyBytes (it sets expectedSize = maxBodyBytes when req.ContentLength < 0), producing the exact divergence: OPA is told "not truncated", but the body was truncated, and the backend receives the whole thing.

Reachability

  1. Deployment runs opaAuthorizeRequestWithBody with a body-inspecting policy that follows the GHSA-8qqm mitigation (`allow if…
Record
GHSA-5gpm-rgj3-9q76
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N
Weakness
CWE-863
Updated
2026-11-02
OSVGO-2026-6495 No score

Skipper has OPA body-authz bypass: truncated_body mitigation fails open on chunked/HTTP-2 (incomplete fix GHSA-8qqm-fp2q-v734) in github.com/zalando/skipper

Skipper has OPA body-authz bypass: truncated_body mitigation fails open on chunked/HTTP-2 (incomplete fix GHSA-8qqm-fp2q-v734) in github.com/zalando/skipper

Record
GO-2026-6495
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
github.com/zalando/skipper
Go
before 0.27.37
0.27.37

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-86043 is a high vulnerability (CVSS 7.5) in Zalando Skipper, published September 16, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.45%, the 39th percentile. Fixed in github.com/zalando/skipper 0.27.37.

References

This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open