A AegiFlow
CRITICALCVSS 9.1

GHSA-r277-6w6q-xmqw

kin-openapi: ValidationHandler.Load() Fail-Open Authentication Bypass via NoopAuthenticationFunc Default

Published
2026-07-24
Modified
2026-07-24
Sources
github-advisory

Summary

### Summary `ValidationHandler.Load()` in `getkin/kin-openapi` silently replaces a nil `AuthenticationFunc` with `NoopAuthenticationFunc`, which always returns `nil` without performing any credential check. Because this substitution happens unconditionally when the caller omits the field, every OpenAPI `security` requirement declared in the spec is silently satisfied for unauthenticated requests. An unauthenticated remote attacker can reach handlers for routes whose OpenAPI operation requires an API key, OAuth token, or any other security scheme if the application relies on `ValidationHandler` as its enforcement middleware. ### Details `ValidationHandler` is an HTTP middleware exported by `openapi3filter` that validates incoming requests and responses against a loaded OpenAPI specification. Its `Load()` method initialises default fields before the handler begins serving: ```go // openapi3filter/validation_handler.go:47-49 if h.AuthenticationFunc == nil { h.AuthenticationFunc = NoopAuthenticationFunc } ``` `NoopAuthenticationFunc` is defined as: ```go // openapi3filter/validation_handler.go:17-18 func NoopAuthenticationFunc(context.Context, *AuthenticationInput) error { return nil } ``` It always returns `nil`, meaning every security scheme check it handles is automatically approved. When a request arrives, `ServeHTTP` → `before` → `validateRequest` assembles a `RequestValidationInput` with the current `AuthenticationFunc` (now the no-op) injected into `Options`: ```go // openapi3filter/validation_handler.go:91-103 options := &Options{ AuthenticationFunc: h.AuthenticationFunc, } requestValidationInput := &RequestValidationInput{ Request: r, PathParams: pathParams, Route: route, Options: options, } if err = ValidateRequest(r.Context(), requestValidationInput); err != nil { return err } ``` Inside `ValidateRequest`, each security requirement calls `options.AuthenticationFunc`: ```go // openapi3filter/validate_request.go:436-438 f := options.AuthenticationFunc if f == nil { return ErrAuthenticationServiceMissing // fail-closed path — never reached via ValidationHandler } // ... // openapi3filter/validate_request.go:497-503 if err := f(ctx, &AuthenticationInput{...}); err != nil { return err } ``` Because `f` is the no-op (not `nil`), the `ErrAuthenticationServiceMissing` guard is never triggered and `f(...)` returns `nil`, clearing the security requirement. Control then proceeds to the protected handler (`validation_handler.go:61-62`). The critical contradiction is that callers who use `ValidateRequest` directly with a nil `AuthenticationFunc` get fail-closed behavior (`ErrAuthenticationServiceMissing`), while callers who use the higher-level `ValidationHandler` with a nil `AuthenticationFunc` get fail-open behavior. Since omitting `AuthenticationFunc` is the natural default, the majority of real-world integrations are vulnerable. Affected source file and line: `openapi3filter/validation_handler.go:47–49` (commit `30e2923`, tag `v0.143.0`). ### PoC **Environment** ``` Docker (any version supporting multi-stage builds) Go 1.25 (inside the container via golang:1.25-alpine) getkin/kin-openapi v0.143.0 (local source copy) ``` **Step 1 — Build the Docker image** From the repository root (parent of `vuln-001/`): ```bash docker build \ -t vuln001-auth-bypass-poc \ -f vuln-001/Dockerfile \ reports/github_web_233_getkin__kin-openapi ``` The `Dockerfile` copies the local `kin-openapi` source into `/kin-openapi/` inside the image and builds a Go binary (`/poc-binary`) from `main.go`. The `go.mod` inside the image uses a `replace` directive pointing to `/kin-openapi`, so no network access to the Go module proxy is required. **Step 2 — Run the container** ```bash docker run --rm --network none vuln001-auth-bypass-poc ``` **Step 3 (alternative) — Use the Python helper** ```bash python3 vuln-001/poc.py --no-cleanup ``` **What the PoC does** `main.go` creates a tempor

Affected packages

EcosystemPackageAffected versionsFixed versions
Gogithub.com/getkin/kin-openapi0.144.0

Remediation: Upgrade to 0.144.0 or later.

References

Includes data from the GitHub Advisory Database, licensed under CC-BY 4.0.