---
id: "CVE-2026-100347"
page: "https://infrastack.ai/live/CVE-2026-100347"
kind: "vulnerability"
aliases: ["CVE-2026-100347", "GHSA-fh4f-47mf-f2gj", "GO-2026-6783"]
title: "kin-openapi: Unauthenticated panic (DoS) in openapi3filter legacy router via non-canonical/unsupported HTTP method on a static path"
severity: "high"
cvss: 5.3
epss: 0.00515
exploited: false
status: "open"
category: "package"
products: [{"name": "github.com/getkin/kin-openapi", "fixed": ["0.145.0"], "affected": "< 0.145.0", "ecosystem": "go"}, {"name": "github.com/getkin/kin-openapi", "fixed": ["0.145.0"], "affected": "<= 0.144.0", "ecosystem": "go"}]
ecosystems: ["go"]
tags: ["api-server", "cwe-20", "cwe-248", "go", "kin-openapi", "openapi", "package"]
not_affected_if: ["no-http-router", "offline-spec-parsing"]
published_at: "2026-10-15T16:17:30+00:00"
first_seen_at: "2026-11-06T00:09:04+00:00"
updated_at: "2026-11-06T00:19:08+00:00"
sources: [{"source": "govuln", "url": "https://pkg.go.dev/vuln/GO-2026-6783", "first_seen_at": "2026-11-06T00:09:04+00:00"}, {"source": "nvd", "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-100347", "first_seen_at": "2026-11-06T00:19:01+00:00"}, {"source": "ghsa", "url": "https://github.com/advisories/GHSA-fh4f-47mf-f2gj", "first_seen_at": "2026-11-06T00:19:08+00:00"}]
exploit_sources: [{"type": "epss", "score": 0.00515, "url": "https://api.first.org/data/v1/epss?cve=CVE-2026-100347"}]
---

# kin-openapi: Unauthenticated panic (DoS) in openapi3filter legacy router via non-canonical/unsupported HTTP method on a static path

Link for people: https://infrastack.ai/live/CVE-2026-100347 (this .md is for agents)

The openapi3filter legacy router in the Go library kin-openapi panics when it receives a non-canonical or unsupported HTTP method on a static path. An unauthenticated remote request can therefore crash any service that uses this router, causing denial of service.

_Summary, check and fix written by a model from the sources; labelled as such._

## Affected

- go:github.com/getkin/kin-openapi affected < 0.145.0 fixed 0.145.0
- go:github.com/getkin/kin-openapi affected <= 0.144.0 fixed 0.145.0

## How to check

- Check whether the module `github.com/getkin/kin-openapi` is in `go.mod` and which version is pinned
- Run `go list -m github.com/getkin/kin-openapi` to see the resolved version
- Check whether the code uses the openapi3filter legacy router to validate incoming requests

## Fix

- `github.com/getkin/kin-openapi` `0.145.0`

## Timeline

- 2026-11-06T00:09:04+00:00 govuln https://pkg.go.dev/vuln/GO-2026-6783
- 2026-11-06T00:19:01+00:00 nvd https://nvd.nist.gov/vuln/detail/CVE-2026-100347
- 2026-11-06T00:19:08+00:00 ghsa https://github.com/advisories/GHSA-fh4f-47mf-f2gj

## Documents

- [advisory] Vendor advisory: github.com https://github.com/getkin/kin-openapi/security/advisories/GHSA-fh4f-47mf-f2gj
- [advisory] Maintainer's advisory: api.github.com https://api.github.com/repos/getkin/kin-openapi/security-advisories/GHSA-fh4f-47mf-f2gj
- [fix] Patch: github.com https://github.com/getkin/kin-openapi/commit/f1a5b523b82868d2d9be2e116b4e942892be72c3
- [fix] Release notes: github.com https://github.com/getkin/kin-openapi/releases/tag/v0.145.0

## From the sources

## Summary
The `openapi3filter.ValidationHandler` (the exported, documented request-validation middleware) hard-wires the legacy router (`routers/legacy`). That router matches the incoming request method verbatim against a trie built exclusively from upper-cased canonical HTTP methods. A request carrying a method token that is not one of the 9 standard methods — a legitimate-but-unsupported token such as `PROPFIND`, or a non-canonical case variant such as lowercase `get` — misses the trie, leaves `route == nil`, and for an existing **static** path falls through to `PathItem.GetOperation(method)`, whose `default:` case calls `panic(...)`. The panic fires inside route resolution, **before any authentication** runs. This is an unauthenticated, remotely triggerable denial of service (recovered per-connection panic + unbounded error-log growth).

## Root Cause
- `openapi3filter/validation_handler.go:39` — `ValidationHandler.Load()` always constructs `legacyrouter.NewRouter(doc)`; there is no alternative router option on this path.
- `routers/legacy/router.go:109` — the request method is used verbatim (`method, url := req.Method, ...`); there is no canonicalization or rejection of unknown method tokens.
- `routers/legacy/router.go:69-70` — the trie is populated with `strings.ToUpper(method)` keys taken from `pathItem.Operations()` (canonical `http.Method*` constants only).
- `routers/legacy/router.go:141` — `root.Match(method + " " + remainingPath)` misses for a non-canonical/unsupported method → `route == nil`.
- `routers/legacy/router.go:146-150` — in the `route == nil` block, `doc.Paths.Value(path)` returns non-nil for an existing static path, and control reaches `pathItem.GetOperation(method)`.
- `openapi3/path_item.go:174` — `GetOperation`'s `switch method` has no matching case → `default: panic(fmt.Errorf("unsupported HTTP method %q", method))`.

## Impact
An unauthenticated attacker sends a single request with a non-standard HTTP method token to any existing static path. The handler goroutine panics; Go's `net/http` recovers the panic per connection (process survives), aborts the connection (client sees a reset / 500), and logs a full stack trace. Repeated requests cause connection churn and unbounded `http: panic serving` log growth, and the request never reaches authentication. Availability impact (A:L) under the default synchronous `ValidationHandler` middleware; on non-net/http hosts or when reached on an application goroutine the ceiling is a full crash.

## Proof of Concept
Serve any spec with a static path (e.g. `/ping`) behind `openapi3filter.ValidationHandler`, then:
```
printf 'PROPFIND /ping HTTP/1.1\r\nHost: x\r\n\r\n' | nc target 8080   # connection aborted (panic)
printf 'get /ping HTTP/1.1\r\nHost: x\r\n\r\n'      | nc target 8080   # connection aborted (panic)
printf 'GET /ping HTTP/1.1\r\nHost: x\r\n\r\n'      | nc target 8080   # 200 OK (process survived)
```
Reproduced end-to-end against a real `net/http.Server` + `ValidationHandler`: `PROPFIND /ping` and lowercase `get /ping` both abort the connection with a panic at `path_item.go:174` (stack: `GetOperation` <- `legacy.FindRoute` router.go:150 <- `ValidationHandler.validateRequest` validation_handler.go:84); the process stays alive and subsequent `GET /ping` returns 200.

## Attack Chain
1. Entry: unauthenticated `PROPFIND /ping HTTP/1.1` (any known static path). Guard: net/http method validation. Bypass proof: net/http accepts any valid HTTP token as a method — `PROPFIND` and lowercase `get` both reach the handler.
2. Route match: `legacy/router.go:141` `root.Match("PROPFIND /ping")`. Guard: trie match. Bypass proof: trie holds only upper-cased canonical methods → miss → `route == nil`.
3. `route == nil` block: `router.go:146` `doc.Paths.Value("/ping")` → non-nil for an existing static path (exact map lookup). Guard: `pathItem == nil` check (l.147). Bypass proof: static path exists → not nil → proceeds.
4. Sink: `router.go:150` `pathItem.GetOperation("PROPFIND")` → `path_item.go:174` `default: panic(...)`.
5. Impact: handler goroutine panics; net/http recovers per connection; request never reaches auth.

## Bypass Evidence
- net/http does NOT reject non-standard method tokens — confirmed empirically: `PROPFIND` and lowercase `get` both reached the handler and panicked.
- No canonicalization/rejection exists between `FindRoute` entry and `GetOperation`; `req.Method` is used verbatim (router.go:109).
- `git show v0.144.0:openapi3/path_item.go` shows `panic(...)` at line 174; `git show v0.144.0:routers/legacy/router.go` shows verbatim method use and the unguarded `GetOperation` call. `git log v0.144.0..HEAD` on these files is empty (no post-tag fix).

## Scoping Note
The panic requires the request path to be an exact static (non-templated) key in the served spec. A concrete path against a `/{id}` template returns a clean 500 (not a panic), because `Paths.Value` is an exact map lookup. Static paths (`/health`, `/login`, `/version`, `/metrics`, `/ping`, `/`) are ubiquitous in real specs and discoverable from public specs/standard endpoints, so a vulnerable target almost always exists. This makes the finding arguably broader than existing panic advisories, as it needs no special spec construct — any static path suffices.

## Affected Versions
`<= 0.144.0` (present on the latest release tag v0.144.0; long-standing; no patched version).

## Suggested Fix
In the legacy router, canonicalize/validate the request method before route resolution and return `ErrMethodNotAllowed`/`ErrPathNotFound` for unknown methods, or make `PathItem.GetOperation` return an error (nil) for unrecognized methods instead of calling `panic`.

---
Reported by **zx (Jace)** — GitHub: @manus-use

---

_Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai_
