GHSA-jpcw-4wr7-c3vq
kin-openapi openapi3filter: unauthenticated nil-pointer panic when validating a request against a `content` parameter whose media type has no schema
Summary
| Field | Value | |---|---| | Ecosystem | Go | | Package | `github.com/getkin/kin-openapi` | | Affected versions | `<= 0.143.0` (introduced in `v0.2.0`, PR #90, 2019-05-07; reproduced on `HEAD` `30e2923`) | | Patched versions | 0.144.0 | --- ### Summary `openapi3filter.ValidateRequest` contains a NULL-pointer-dereference denial of service: any **unauthenticated** client can crash the request-validation path with a **single** HTTP request. When an operation declares a `content` parameter (as opposed to a `schema` parameter) whose media type object has **no `schema`**, request validation dereferences that missing schema and panics. The document is legal under the OpenAPI Specification — kin-openapi's own `doc.Validate()` accepts it — and the defect affects **both OpenAPI 3.0.x and 3.1.x**. Depending on how the library is wired into the server (see Impact), this ranges from a per-request abort with unbounded panic-log growth to a full remote process crash. ### Details The decoder used for `content` parameters when no custom `ParamDecoder` is configured (the library default), `defaultContentParameterDecoder`, dereferences the media-type schema without a nil check. `openapi3filter/req_resp_decoder.go`, around line 197: ```go mt := content.Get("application/json") if mt == nil { // media-type OBJECT is guarded ... err = fmt.Errorf("parameter %q has no content schema", param.Name) return } outSchema = mt.Schema.Value // ... but mt.Schema is NOT — panics when nil ``` The function guards `param.Content == nil`, `len(content) != 1`, and `mt == nil`, but never `mt.Schema == nil`. **Why a schema-less content parameter is legal** (so the sink is reachable — `doc.Validate()` returns no error), in both 3.0.x and 3.1.x: - `openapi3/parameter.go` — `Parameter.Validate` only enforces *exactly one of `schema` XOR `content`*; a parameter with `content` (and no `schema`) satisfies it. - `openapi3/media_type.go` — `MediaType.Validate` validates the schema **only when it is non-nil**, so an absent schema is not a validation error. **Call path to the panic:** ``` ValidateRequest openapi3filter/validate_request.go:83 └─ ValidateParameter openapi3filter/validate_request.go:177 (parameter.Content != nil) └─ decodeContentParameter openapi3filter/req_resp_decoder.go:166 (attacker supplies value ⇒ found) └─ defaultContentParameterDecoder openapi3filter/req_resp_decoder.go:197 ← nil deref / panic ``` **Authentication note:** `ValidateRequest` validates security *before* parameters, but the panic is reachable **without credentials** whenever the target operation declares no security requirement, or when no `AuthenticationFunc` is configured (it is opt-in). A single unauthenticated operation anywhere in the served spec is sufficient. If an operation *does* declare security and a rejecting `AuthenticationFunc` is wired, that request is rejected before decoding. ### PoC Reproduced end-to-end against `HEAD` (`30e2923`) with a real `net/http` server and a stock `http.Client`. **1. Minimal OpenAPI 3.0.3 document** (legal — `doc.Validate()` passes). The `cfg` query parameter uses `content` with an `application/json` media type that has **no `schema`**: ```yaml openapi: 3.0.3 info: {title: poc, version: "1.0.0"} paths: /c: get: parameters: - name: cfg in: query content: application/json: {} # media type object with NO schema responses: "200": {description: ok} ``` **2. A complete, self-contained program.** Drop this into a directory inside a checkout of `github.com/getkin/kin-openapi` and run it with `go run .`. It loads the document above, asserts `doc.Validate()` accepts it (proving reachability), serves it behind request validation exactly as the recommended middleware does, and sends one unauthenticated `GET /c?cfg=1`: ```go package main import ( "context"
Affected packages
| Ecosystem | Package | Affected versions | Fixed versions |
|---|---|---|---|
| Go | github.com/getkin/kin-openapi | — | 0.144.0 |
Remediation: Upgrade to 0.144.0 or later.
References
Includes data from the GitHub Advisory Database, licensed under CC-BY 4.0.