CVE-2026-86043
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.
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
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 High
CVSS: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 High
CVSS: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 withgithub.com/open-policy-agent/opa-envoy-pluginenvoyauth/request.go→getParsedBody/checkIfHTTPBodyTruncated. Filter:opaAuthorizeRequestWithBody. - Affected versions:
<= 0.27.33(current HEADe7d7014c). Thetruncated_bodymitigation 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, commit1be950cd#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
- Deployment runs
opaAuthorizeRequestWithBodywith a body-inspecting policy that follows the GHSA-8qqm mitigation (`allow if…
- Record
GHSA-5gpm-rgj3-9q76- CVSS 3.1
- 7.5 High
CVSS: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 High
CVSS: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 High
CVSS: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 withgithub.com/open-policy-agent/opa-envoy-pluginenvoyauth/request.go→getParsedBody/checkIfHTTPBodyTruncated. Filter:opaAuthorizeRequestWithBody. - Affected versions:
<= 0.27.33(current HEADe7d7014c). Thetruncated_bodymitigation 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, commit1be950cd#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
- Deployment runs
opaAuthorizeRequestWithBodywith a body-inspecting policy that follows the GHSA-8qqm mitigation (`allow if…
- Record
GHSA-5gpm-rgj3-9q76- CVSS 3.1
- 7.5 High
CVSS: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
| Package | Affected | Fixed |
|---|---|---|
github.com/zalando/skipperGo |
before 0.27.37 | 0.27.37 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE 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
github.com/zalando/skipper/security/advisories/GHSA-5gpm-rgj3-9q76
github.com/zalando/skipper/commit/2cfceabaa6ff0af65b312dcb9bcbe84691b9d507
github.com/zalando/skipper/releases/tag/v0.27.35
github.com/zalando/skipper/tree/v0.27.35
nvd.nist.gov/vuln/detail/CVE-2026-86043
github.com/zalando/skipper/releases/tag/v0.27.37
github.com/advisories/GHSA-5gpm-rgj3-9q76
github.com/CVEProject/cvelistV5/tree/main/cves/2026/86xxx/CVE-2026-86043.json
github.com/zalando/skipper
Left out here: the rest of 2 source descriptions. The JSON record has them.