Aug 22, 2026·6 min read·2 visits
Unauthenticated remote attackers can crash servers using getkin/kin-openapi (v0.10.0 to v0.140.0) by transmitting a malformed multipart/form-data request, triggering a nil-pointer dereference panic in the error validation encoder.
CVE-2026-76905 is a high-severity Denial of Service (DoS) vulnerability in the getkin/kin-openapi library, specifically inside the openapi3filter sub-package. When processing multipart/form-data request validation errors, a missing nil-pointer guard causes a Go runtime panic during error formatting. This panic terminates the active server process if no recovery handler is present, resulting in a total denial of service. The vulnerability affects versions from v0.10.0 to v0.140.0, and is resolved in v0.141.0.
The getkin/kin-openapi library is a standard tool in the Go ecosystem for validating, parsing, and verifying HTTP traffic against OpenAPI specification files. Within this ecosystem, the openapi3filter sub-package is frequently implemented as request-validation middleware. This middleware exposes an attack surface to arbitrary remote inputs, parsing request parameters and incoming message bodies before handing them off to downstream controllers.
When openapi3filter encounters a schema discrepancy, it constructs a structural parsing or validation error representation. Downstream services routinely invoke validation helpers such as openapi3filter.ConvertErrors or the ValidationErrorEncoder to translate these internally generated validation errors into client-facing JSON objects. This conversion step acts as the precise point of failure.
The underlying security issue resides within the error translation logic. During parsing of certain complex payloads, the translation routine attempts to access properties of structural references that were never initialized. This logic gap results in a NULL pointer dereference, classified under CWE-476. The vulnerability manifests when formatting validation errors for malformed requests.
The bug is located within the convertParseError helper function inside openapi3filter/validation_error_encoder.go. The validation subsystem defines a core struct named RequestError which maintains metadata regarding the validation failure context. A RequestError can point to parameter-based input violations or body-based input violations, but never both simultaneously.
When a request body is validated (such as a multipart or JSON structure), the parameter validation struct member e.Parameter is explicitly initialized as nil. However, if the error relates to a URI query parameter, e.Parameter contains a reference to the active parameter specification. This logic expects downstream code paths to respect the optional nature of this property.
During multipart/form-data processing, a non-string and non-numeric scalar field that violates schema type guidelines yields a nested structure containing an outer *ParseError wrapping an inner core failure. This nesting triggers a specific code branch in convertParseError that attempts to verify whether the root cause represents an invalid query parameter format.
The logic attempts to evaluate rootErr.Kind == KindInvalidFormat && e.Parameter.In == "query". Because the validation error originated inside the request body, e.Parameter is nil. When the engine attempts to evaluate e.Parameter.In, it dereferences a NULL pointer, throwing a panic that is not recovered inside the validation library itself.
Analyzing the vulnerable logic before and after commit 1d0a337c9b1570fab283be8a04c8af6e43b9a22c reveals the exact structural fault and its corrective patch.
Prior to the patch, the vulnerability in openapi3filter/validation_error_encoder.go was structured as follows:
func convertParseError(e *RequestError, innerErr *ParseError) *ValidationError {
// ...
} else if innerErr.RootCause() != nil {
// e.Parameter is dereferenced directly without verifying if it is nil
if rootErr, ok := innerErr.Cause.(*ParseError); ok &&
rootErr.Kind == KindInvalidFormat && e.Parameter.In == "query" {
return &ValidationError{
Status: http.StatusBadRequest,
Title: fmt.Sprintf("parameter %q in %s is invalid: %v is %s",
e.Parameter.Name, e.Parameter.In, rootErr.Value, rootErr.Reason),
}
}
return &ValidationError{
Status: http.StatusBadRequest,
Title: innerErr.Reason,
}
}
return nil
}The corresponding patch introduces a strict logical boundary that prevents NULL dereferencing. It updates the conditional branch using Go's short-circuit evaluation behavior:
func convertParseError(e *RequestError, innerErr *ParseError) *ValidationError {
} else if innerErr.RootCause() != nil {
if rootErr, ok := innerErr.Cause.(*ParseError); ok &&
- rootErr.Kind == KindInvalidFormat && e.Parameter.In == "query" {
+ rootErr.Kind == KindInvalidFormat && e.Parameter != nil && e.Parameter.In == "query" {
return &ValidationError{
Status: http.StatusBadRequest,
Title: fmt.Sprintf("parameter %q in %s is invalid: %v is %s",
e.Parameter.Name, e.Parameter.In, rootErr.Value, rootErr.Reason),
}
}
+ // For body parse errors (e.Parameter == nil) the outer ParseError's
+ // Reason is often empty, e.g. the multipart decoder wraps a part's
+ // *ParseError without setting one. Fall back to the full error text so
+ // the response still carries a meaningful message.
+ title := innerErr.Reason
+ if title == "" {
+ title = innerErr.Error()
+ }
return &ValidationError{
Status: http.StatusBadRequest,
- Title: innerErr.Reason,
+ Title: title,
}
}
return nil
}By placing e.Parameter != nil before e.Parameter.In == "query", any body-based request error causes the logical evaluation of the if statement to fail immediately. The engine skips evaluating the properties of the nil reference, neutralizing the panic. The added fallback title formatting ensures that body-parsing errors return a valid description.
Exploiting CVE-2026-76905 requires a simple delivery sequence. The targeted application must process validation errors using openapi3filter.ConvertErrors or ValidationErrorEncoder to process user input failures.
The attack is initiated by submitting a multipart request containing a data representation error. The targeted API endpoint must be configured to process multipart/form-data with an OpenAPI schema containing a non-string or non-boolean scalar (e.g., an integer). The attacker transmits a payload containing a non-numeric string where the integer value is expected.
POST /v1/upload HTTP/1.1
Host: target-api.internal
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryXyZ
Content-Length: 185
------WebKitFormBoundaryXyZ
Content-Disposition: form-data; name="age"
notanumber
------WebKitFormBoundaryXyZ--Upon processing the boundary parts, the server's internal parser fails to map "notanumber" to an integer object. It initializes a nested ParseError containing the structural failure but omits the initialization of e.Parameter. When the app formats the failure with ConvertErrors, the service dereferences e.Parameter, throwing a panic that shuts down the entire thread.
The primary impact is service unavailability. A single, small payload containing a malformed boundary value can terminate the active server process.
In Go, unrecovered panics are fatal. Unlike languages where exceptions are confined to localized runtime execution spaces, a Go panic that escapes the active HTTP routine halts the parent process. This results in an absolute Denial of Service (DoS) for all clients interacting with the system.
The vulnerability does not allow remote code execution, file system access, or privilege escalation. It has a CVSS v3.1 score of 7.5, reflecting a network-exploitable vector that requires low complexity and no special privilege states. The absence of data leakage or execution control limits the scope to availability.
The definitive remediation for CVE-2026-76905 is updating the dependency version of github.com/getkin/kin-openapi to version v0.141.0 or higher.
If upgrading is not immediately possible, implement a structural panic-recovery middleware block. This wrapper catches escaped runtime panics and maps them to a normal HTTP error state, such as a 500 Internal Server Error, protecting the parent process.
func PanicRecoveryMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer func() {
if err := recover(); err != nil {
// Prevent server shutdown by catching the runtime error
log.Printf("[SECURITY] Recovered from validation panic: %v", err)
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(`{"error":"Internal Server Error"}`))
}
}()
next.ServeHTTP(w, r)
})
}Additionally, validation processes can be modified to bypass calling ConvertErrors() when formatting incoming schema issues. Instead, check the error type directly in user code to generate client responses safely.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
github.com/getkin/kin-openapi getkin | >= 0.10.0, < 0.141.0 | v0.141.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-476 |
| Attack Vector | Network |
| CVSS Score | 7.5 |
| EPSS Percentile | N/A |
| Impact | Denial of Service (DoS) |
| Exploit Status | Proof-of-Concept |
| KEV Status | Not Listed |
A NULL pointer dereference occurs when the application attempts to read or write to a memory address assumed to be valid but is instead NULL, triggering a crash.
A critical path traversal vulnerability in Atlantis allows authenticated users or repository contributors to execute directory operations outside of the repository directory boundary via crafted workspace parameters in configuration files or API requests.
A critical server-side template injection (SSTI) vulnerability exists in the Volt template engine of the Phalcon PHP framework. In versions 5.15.0 and earlier, raw AST token values for filter arguments in the 'join' filter are directly spliced into the generated PHP template code. This allows an attacker who can influence Volt templates to execute arbitrary PHP code during template rendering.
CVE-2026-61539 is a critical remote code execution vulnerability in Xinference, an inference API framework for open-source LLMs. In version 2.5.0 and earlier, model-generated outputs representing Llama3 tool calls are passed directly to Python's built-in eval() function inside the parser components. By manipulating conversational input or injecting instructions, an attacker can influence the LLM to output a Python expression containing malicious system commands, resulting in unauthenticated remote code execution on the host. This vulnerability has been resolved in Xinference version 2.7.0.
An uncontrolled resource consumption vulnerability (CWE-400/CWE-789) exists within the kin-openapi Go library prior to version 0.142.0. The vulnerability occurs during the processing of highly sparse array indexes inside query parameters defined in deepObject style. An unauthenticated remote attacker can exploit this flaw to cause an immediate Out-of-Memory (OOM) crash of the target application.
A critical prototype pollution and sandbox escape vulnerability was discovered in the JSONata query and transformation library before versions 1.8.8 and 2.2.0. By providing a malicious JSONata expression that bypasses ownership checks on object properties, remote attackers can execute arbitrary code in the context of the host Node.js application.
CVE-2026-63135 is a critical stored Cross-Site Scripting (XSS) vulnerability affecting YOURLS (Your Own URL Shortener) versions 1.5.1 up to (but not including) 1.10.4. Unauthenticated remote attackers can inject malicious JavaScript arrays by crafting an HTTP Referer header sent to a short URL redirect. This value is saved in the database logs and executed without context-aware escaping when an administrative user views the corresponding statistics visualization page.