{"description":"Trending threats, MITRE ATT\u0026CK coverage, and detection metadata. Fed continuously.","feed_url":"https://feed.craftedsignal.io/tags/opa/feed.json","home_page_url":"https://feed.craftedsignal.io/","items":[{"_cs_actors":[],"_cs_cpes":[],"_cs_cves":[],"_cs_exploited":false,"_cs_has_poc":false,"_cs_poc_references":[],"_cs_products":["skipper (\u003c= v0.26.8)"],"_cs_severities":["high"],"_cs_tags":["vulnerability","api-gateway","security-bypass","opa","network"],"_cs_type":"advisory","_cs_vendors":["Zalando"],"content_html":"\u003cp\u003eA significant vulnerability (GHSA-659f-rgp5-w4wf) has been identified in \u003ccode\u003ezalando/skipper\u003c/code\u003e versions \u003ccode\u003e\u0026lt;= v0.26.8\u003c/code\u003e that allows threat actors to bypass security policies enforced by the \u003ccode\u003eopaAuthorizeRequestWithBody\u003c/code\u003e filter. This bypass occurs when HTTP/1.1 requests use \u003ccode\u003eTransfer-Encoding: chunked\u003c/code\u003e or HTTP/2 requests omit the \u003ccode\u003econtent-length\u003c/code\u003e pseudo-header. Under these conditions, the \u003ccode\u003eOpenPolicyAgentInstance.ExtractHttpBodyOptionally\u003c/code\u003e helper in Skipper incorrectly produces an empty \u003ccode\u003eraw_body\u003c/code\u003e for OpenPolicyAgent (OPA) policies, even though the full, potentially malicious, body is forwarded to the upstream service. This means OPA policies designed to inspect and deny requests based on body content (e.g., for \u003ccode\u003eadmin=true\u003c/code\u003e fields, content moderation, or schema validation) will evaluate against an empty document and typically default to allowing the request, effectively neutralizing a critical layer of defense. The vulnerability affects operators relying on Skipper to protect private upstream services using body-content checks.\u003c/p\u003e\n\u003ch2 id=\"attack-chain\"\u003eAttack Chain\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e\u003cstrong\u003eAttacker identifies Skipper instance\u003c/strong\u003e: An attacker identifies a \u003ccode\u003ezalando/skipper\u003c/code\u003e API Gateway instance protecting a backend service, configured with the \u003ccode\u003eopaAuthorizeRequestWithBody\u003c/code\u003e filter.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eAttacker crafts malicious HTTP request\u003c/strong\u003e: The attacker prepares an HTTP POST request containing a payload intended to be blocked by an OPA policy (e.g., \u003ccode\u003e{\u0026quot;admin\u0026quot;:true}\u003c/code\u003e to gain administrative privileges).\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eApplies bypass framing\u003c/strong\u003e: The attacker sends the request using HTTP/1.1 with \u003ccode\u003eTransfer-Encoding: chunked\u003c/code\u003e headers or as an HTTP/2 request without a \u003ccode\u003eContent-Length\u003c/code\u003e pseudo-header.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eSkipper receives and parses request\u003c/strong\u003e: The \u003ccode\u003ezalando/skipper\u003c/code\u003e instance receives the request. Due to the specific framing, Go's \u003ccode\u003enet/http\u003c/code\u003e parser sets \u003ccode\u003ereq.ContentLength = -1\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eOPA body extraction fails\u003c/strong\u003e: The \u003ccode\u003eExtractHttpBodyOptionally\u003c/code\u003e function, which is supposed to buffer the body for OPA, checks \u003ccode\u003ereq.ContentLength \u0026lt;= maxBodyBytes\u003c/code\u003e. While \u003ccode\u003e-1\u003c/code\u003e passes this check, the subsequent \u003ccode\u003efillBuffer\u003c/code\u003e loop's condition \u003ccode\u003eint64(m.bodyBuffer.Len()) \u0026lt; expectedSize\u003c/code\u003e (\u003ccode\u003e0 \u0026lt; -1\u003c/code\u003e) is immediately false, preventing any body data from being read. An empty \u003ccode\u003eraw_body\u003c/code\u003e is then passed to the OPA SDK.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eOPA policy grants unauthorized access\u003c/strong\u003e: The OPA policy, expecting to evaluate \u003ccode\u003einput.parsed_body\u003c/code\u003e against the actual request body, instead receives an empty document. If the policy is designed to deny based on specific content (e.g., \u003ccode\u003einput.parsed_body.admin == true\u003c/code\u003e), it will default to \u0026quot;allow\u0026quot; because the condition is not met in the empty input.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eSkipper forwards full payload\u003c/strong\u003e: Despite the OPA policy effectively being bypassed, Skipper proceeds to forward the \u003cem\u003eoriginal, full, and uninspected malicious payload\u003c/em\u003e (e.g., \u003ccode\u003e{\u0026quot;admin\u0026quot;:true}\u003c/code\u003e) to the backend upstream service.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eUpstream processes unauthorized request\u003c/strong\u003e: The upstream service receives and processes the unauthorized request and payload, potentially leading to privilege escalation, data modification, or remote code execution, depending on the backend's vulnerabilities.\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"impact\"\u003eImpact\u003c/h2\u003e\n\u003cp\u003eThis vulnerability allows for a complete bypass of critical security controls implemented via OpenPolicyAgent for body content inspection. Organizations using \u003ccode\u003ezalando/skipper\u003c/code\u003e with \u003ccode\u003eopaAuthorizeRequestWithBody\u003c/code\u003e policies to enforce granular authorization, content moderation, or schema validation for incoming requests are at risk. A successful exploitation enables unauthenticated attackers to send arbitrary payloads that OPA policies were explicitly designed to block, potentially leading to unauthorized data access, privilege escalation, command injection, or other severe compromises of protected backend services. There is no observed victim count or specific sector targeting mentioned, but any organization deploying Skipper as an API gateway is affected.\u003c/p\u003e\n\u003ch2 id=\"recommendation\"\u003eRecommendation\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eUpgrade \u003ccode\u003ezalando/skipper\u003c/code\u003e to a version that contains the fix for GHSA-659f-rgp5-w4wf immediately upon availability.\u003c/li\u003e\n\u003cli\u003eReview all OPA policies utilizing \u003ccode\u003einput.parsed_body\u003c/code\u003e with the \u003ccode\u003eopaAuthorizeRequestWithBody\u003c/code\u003e filter to understand their susceptibility to this bypass.\u003c/li\u003e\n\u003cli\u003eDeploy the Sigma rule below to detect attempts to use \u003ccode\u003eTransfer-Encoding: chunked\u003c/code\u003e in conjunction with body content that would typically be denied by OPA policies.\u003c/li\u003e\n\u003cli\u003eEnsure webserver logs or API gateway logs capture HTTP headers, specifically \u003ccode\u003eTransfer-Encoding\u003c/code\u003e, for POST requests to sensitive endpoints.\u003c/li\u003e\n\u003c/ul\u003e\n","date_modified":"2026-07-08T20:27:10Z","date_published":"2026-07-08T20:27:10Z","id":"https://feed.craftedsignal.io/briefs/2026-07-skipper-opa-bypass/","summary":"A critical vulnerability in `zalando/skipper`'s OpenPolicyAgent integration, tracked as GHSA-659f-rgp5-w4wf, allows attackers to bypass `opaAuthorizeRequestWithBody` policies using HTTP/1.1 `Transfer-Encoding: chunked` or HTTP/2 requests lacking a `content-length` pseudo-header, leading to unauthorized access to upstream services with uninspected payloads.","title":"Zalando Skipper OPA Policy Bypass via Chunked Encoding","url":"https://feed.craftedsignal.io/briefs/2026-07-skipper-opa-bypass/"}],"language":"en","title":"CraftedSignal Threat Feed - Opa","version":"https://jsonfeed.org/version/1.1"}