CVE-2026-54247: Skipper Denial of Service Vulnerability
MODERATECVE-2026-54247 is a MODERATE (CVSS 4.3) denial of service vulnerability (CWE-770: Allocation of Resources Without Limits or Throttling) affecting Skipper libraries in the Go ecosystem. The issue involves unbounded request body read in admission webhook causes memory exhaustion dos. Remediation is available by upgrading affected packages to version 0.26.22.
CVE-2026-54247 at a Glance
Security Impact
CVSS: 4.3
The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L).
How to Fix CVE-2026-54247
To remediate this vulnerability, upgrade all affected Skipper dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
Upgrade github.com/zalando/skipper to 0.26.22
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
inspect dependencies for github.com/zalando/skipper
How to Check if You Are Affected
To determine whether your application is affected by CVE-2026-54247, inspect your project dependencies for Skipper:
inspect dependencies for github.com/zalando/skipper
Analyze the terminal output to locate any version of Skipper in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 0.26.22), your application is affected.
Note: Verify declared build manifests and deployed runtime container environments.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-770: Allocation of Resources Without Limits or Throttling, where the product allocates a reusable resource or group of resources on behalf of an actor without imposing any intended restrictions on the size or number of resources that can be allocated. In Skipper, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
CVE-2026-54247 Affected Skipper Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
github.com/zalando/skipper
|
Go |
< 0.26.22
|
0.26.22
|
References
Frequently Asked Questions
What is CVE-2026-54247?
Which Skipper versions are affected?
What version fixes CVE-2026-54247?
Is github.com/zalando/skipper affected?
What is the CVSS score of CVE-2026-54247?
What CWE is associated with CVE-2026-54247?
How can I check Go dependencies for CVE-2026-54247?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-cwxq-rc9x-2jvv",
"modified" : "2026-07-17T18:14:08Z",
"published" : "2026-07-17T18:14:08Z",
"aliases" : [ "CVE-2026-54247" ],
"summary" : "Skipper: Unbounded Request Body Read in Admission Webhook Causes Memory Exhaustion DoS",
"details" : "## Summary\n\nThe Kubernetes admission webhook handler reads the entire request body using `io.ReadAll(r.Body)` without any size limit. Any client that can reach the webhook port within the cluster can send a multi-GB payload, causing the skipper process to exhaust memory and be OOM-killed. This disrupts all Kubernetes admission control, potentially blocking all pod creation and updates.\n\n## Vulnerable Code\n\n```go\n// dataclients/kubernetes/admission/admission.go:76\nbody, err := io.ReadAll(r.Body) // <-- NO SIZE LIMIT\nif err != nil {\n log.Errorf(\"Failed to read request: %v\", err)\n w.WriteHeader(http.StatusInternalServerError)\n invalidRequests.WithLabelValues(admitterName).Inc()\n return\n}\n\nvar review admissionReview\nerr = json.Unmarshal(body, &review)\n```\n\nFor comparison, the OPA filter has a body size limit:\n\n```go\n// filters/openpolicyagent/openpolicyagent.go:68-70\nconst DefaultMaxRequestBodySize = 1 << 20 // 1MB\n\n// OPA uses a bufferedBodyReader with size limits\n```\n\n## Attack Path\n\n1. Attacker identifies the admission webhook endpoint (default: `:9443/admission` or configured path)\n2. Attacker sends: `POST /admission HTTP/1.1, Content-Type: application/json` with a multi-GB request body\n3. `io.ReadAll(r.Body)` allocates unbounded memory for the entire body\n4. Skipper process is OOM-killed by the Kubernetes kubelet\n\n## Permission Boundary Analysis\n\n- **Attacker**: Any client with network access to the admission webhook port within the Kubernetes cluster\n- **Boundary crossed**: Memory safety — unbounded allocation from attacker-controlled input\n- **Preconditions**: Admission webhook endpoint must be network-reachable (default Kubernetes deployment exposes it within cluster network)\n- **Comparison**: OPA filter has `DefaultMaxRequestBodySize` (1MB) and semaphore-based memory limit; admission handler has neither\n\n## Evidence\n\n| File | Lines | Description |\n|------|-------|-------------|\n| `dataclients/kubernetes/admission/admission.go` | 76 | `io.ReadAll(r.Body)` without size limit |\n| `filters/openpolicyagent/openpolicyagent.go` | 68-70 | OPA filter has `DefaultMaxRequestBodySize` = 1MB |\n| `filters/openpolicyagent/openpolicyagent.go` | 1333-1336 | OPA uses `bufferedBodyReader` with size limits |\n\n## Tests\n\n- `dataclients/kubernetes/admission/admission_test.go` exists but **does not test body size limits**\n\n## Impact\n\nThe admission webhook handler reads the entire request body using io.ReadAll(r.Body) without a size limit. An attacker with in-cluster network access and a valid Kubernetes client certificate can send a multi-GB payload to the webhook endpoint, causing the skipper process to exhaust memory and be OOM-killed. This disrupts admission control for Ingress and RouteGroup resources until the process is automatically restarted by the kubelet.\n\nScope of impact: Ingress and RouteGroup admission only — not pod creation or other admission controllers.\n\nRecovery: Kubernetes automatically restarts the OOM-killed process, limiting downtime.\n\nPrerequisites: (1) In-cluster network access to the webhook port, (2) valid Kubernetes client certificate.\n\n## Mitigation\n\n1. Add `http.MaxBytesReader` or equivalent body size limit before `io.ReadAll`\n2. Follow the OPA filter pattern: define `DefaultMaxRequestBodySize` and use a buffered reader with size limits\n3. Add a configurable `--admission-max-body-size` flag",
"severity" : [ {
"type" : "CVSS_V3",
"score" : "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "Go",
"name" : "github.com/zalando/skipper"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "0.26.22"
} ]
} ]
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/zalando/skipper/security/advisories/GHSA-cwxq-rc9x-2jvv"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/zalando/skipper"
}, {
"type" : "WEB",
"url" : "https://github.com/zalando/skipper/releases/tag/v0.26.22"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-770" ],
"severity" : "MODERATE",
"github_reviewed" : true,
"github_reviewed_at" : "2026-07-17T18:14:08Z",
"nvd_published_at" : null
}
}