Jul 25, 2026·5 min read·7 visits
Unauthenticated remote attackers can crash Go web servers using the kin-openapi validation middleware by sending a request containing a parameter whose media type has no defined schema, triggering a fatal NULL pointer dereference.
A NULL pointer dereference vulnerability was discovered in the getkin/kin-openapi Go library. When parsing incoming request parameters that are validated against a content map with an empty media type, the openapi3filter request validation engine attempts to resolve an uninitialized schema pointer. This results in an unhandled Go runtime panic and process termination, yielding an unauthenticated, remote Denial of Service vector.
The getkin/kin-openapi Go package is widely used to load, parse, and validate OpenAPI specifications. Within this package, the openapi3filter module serves as the core request validation engine, verifying that incoming parameters and payloads conform to the defined API schema.
This vulnerability, tracked as GHSA-JPCW-4WR7-C3VQ, is a NULL pointer dereference (CWE-476) occurring within the openapi3filter request parser. The flaw allows an unauthenticated remote attacker to trigger a runtime panic, which crashes the parent process and achieves a Denial of Service.
Because Go processes do not automatically recover from unhandled goroutine panics, this vulnerability poses a severe threat to service availability if global recovery middleware is absent.
The OpenAPI Specification allows API designers to define input parameters using either a direct schema or a content map. Within a content map, developers associate media types with schema structures that govern serialization.
Crucially, the specification dictates that the inner schema property within a media type object is optional. Consequently, specifications with empty media type definitions are fully valid and cleanly pass the initial document parser phase.
At runtime, openapi3filter fails to check if the schema pointer inside the media type is initialized. When parsing an incoming request parameter mapped to an empty media type, the decoder attempts to dereference this uninitialized pointer, leading to a fatal application panic.
The vulnerability resides inside req_resp_decoder.go within the defaultContentParameterDecoder function. The original logic retrieved the media type and resolved the schema pointer without validating its existence.
// Vulnerable Code Path
func defaultContentParameterDecoder(param *openapi3.Parameter, values []string) (outSchema *openapi3.Schema, unmarshal func(string, *openapi3.SchemaRef) (any, error), err error) {
content := param.Content
mt := content.Get("application/json")
if mt == nil {
err = fmt.Errorf("parameter %q has no content schema", param.Name)
return
}
// BUG: mt.Schema is a pointer and can be nil
outSchema = mt.Schema.Value
}To remediate the bug, the maintainers introduced an explicit validation check to ensure the schema reference is initialized before accessing its properties. If mt.Schema is nil, the function returns a structured error rather than dereferencing a nil pointer.
// Patched Code Path (Commit 68ac2affa325514d7d6e731204d6a1edf6bdff64)
func defaultContentParameterDecoder(param *openapi3.Parameter, values []string) (outSchema *openapi3.Schema, unmarshal func(string, *openapi3.SchemaRef) (any, error), err error) {
content := param.Content
mt := content.Get("application/json")
if mt == nil {
err = fmt.Errorf("parameter %q has no content schema", param.Name)
return
}
// FIX: Verify Schema pointer is initialized
if mt.Schema == nil {
err = fmt.Errorf("parameter %q content media type has no schema", param.Name)
return
}
outSchema = mt.Schema.Value
}To exploit this vulnerability, an attacker must identify an API endpoint validated by openapi3filter that utilizes content parameter validation without a defined schema structure. Because the crash occurs during request validation, the attack is executed prior to any business logic processing.
An attacker sends a standard HTTP request targeting the parameter. The request does not require specific credentials or complex delivery payloads, lowering the barrier to entry.
When the application processes the request, the Go runtime triggers a nil pointer dereference panic, stopping the active goroutine. If the HTTP server does not utilize robust panic recovery, the entire service halts immediately.
This vulnerability is classified as a high-severity Denial of Service vector, carrying an assessed CVSS score of 7.5. Because the flaw can be triggered remotely without authentication, it is highly attractive for service disruption campaigns.
No data leakage, privilege escalation, or unauthorized data modification risks are present. The impact is strictly restricted to service availability.
If the target application runs inside containers without automated restart capabilities, a single exploit request can result in prolonged service outages.
The primary remediation is upgrading the getkin/kin-openapi dependency to version v0.144.0 or later. This ensures that parameter schemas are validated prior to parsing.
If immediate upgrading is unfeasible, developers should audit their OpenAPI specifications to ensure every parameter media type includes a defined schema structure. Alternatively, global panic recovery middleware should be implemented to capture goroutine crashes gracefully.
func RecoveryMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer func() {
if err := recover(); err != nil {
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
}
}()
next.ServeHTTP(w, r)
})
}CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
kin-openapi getkin | < v0.144.0 | v0.144.0 |
| Attribute | Detail |
|---|---|
| Vulnerability ID | GHSA-JPCW-4WR7-C3VQ |
| CWE ID | CWE-476 (Null Pointer Dereference) |
| Attack Vector | Network |
| CVSS v3.1 Score | 7.5 (High) |
| Exploit Status | Proof of Concept (PoC) public |
| CISA KEV Status | Not Listed |
| Impact | Denial of Service (DoS) |
A NULL pointer dereference occurs when the application dereferences a pointer that it expects to be valid, but is NULL, typically causing a crash.
A prototype pollution vulnerability (CWE-1321) in the Quasar framework's utility function 'extend' allows unauthenticated remote attackers to modify the global Object.prototype. This vulnerability can lead to application-level logic bypasses, denial of service, or potentially arbitrary code execution depending on downstream implementation.
A critical connection-level Denial of Service (DoS) vulnerability exists in the Yamux stream multiplexer implementation of py-libp2p (versions <= 0.6.0). The flaw allows unauthenticated or authenticated peers to permanently stall a Yamux multiplexed connection by transmitting a single malformed 12-byte header claiming an oversized payload while withholding the payload bytes.
An unauthenticated remote resource exhaustion vulnerability in Amazon aws-smithy-http-server enables denial-of-service (DoS) attacks. Affected versions do not enforce connection limits or header timeouts, allowing standard Slowloris techniques to block server operations.
An authorization bypass vulnerability in the gRPC Watch API of etcd allows low-privileged users to read keys outside of their authorized range. By utilizing an open-ended range request sentinel, the input is prematurely normalized before RBAC validation, misclassifying a range watch as a single-key point query.
An argument injection vulnerability in the AWS Bedrock AgentCore Python SDK allows authenticated users to execute arbitrary commands inside the Code Interpreter sandbox container via crafted Python package specifiers containing shell metacharacters.
A Server-Side Request Forgery (SSRF) vulnerability in FrontMCP allows unauthenticated remote attackers to query internal network services by exploiting the un-guarded background OpenAPI specification polling mechanism.