{"id":"CVE-2026-100353","kind":"vulnerability","aliases":["CVE-2026-100353","GHSA-vrcc-3ch7-hppw","GO-2026-6800"],"related":[],"title":"kin-openapi: Incomplete Fix for GHSA-p6wj-qrr4-pgh5: Three Unpatched nil-Items Panic Paths in openapi3filter","description":"## Summary\n\nThe fix for GHSA-p6wj-qrr4-pgh5 addressed a nil-pointer dereference that occurs when an OpenAPI 3.1 array schema omits the `items` keyword (which is legal under JSON Schema 2020-12). That fix patched three decoder paths: the standalone `parseArray` function, the top-level array check in `UrlencodedBodyDecoder`, and `MultipartBodyDecoder`.\n\nThree additional crash paths were missed. All of them reach the unguarded `urlValuesDecoder.parseArray` method (`openapi3filter/req_resp_decoder.go:576`) or the unguarded array branch in `buildResObj` (line 1015):\n\n1. **Query parameters** with `type: array` and no `items`.\n2. **deepObject** query parameters containing an array property with no `items`.\n3. **URL-encoded request bodies** where the array lives inside an `allOf` / `anyOf` / `oneOf` sub-schema. This path bypasses the guard added by the GHSA-p6wj-qrr4-pgh5 fix, because that guard only inspects top-level properties.\n\nEach path is triggerable by an unauthenticated client and produces a deterministic nil-pointer panic during request validation.\n\n## Details\n### Root Cause\n\nThe three paths patched for GHSA-p6wj-qrr4-pgh5 each received a nil-`items` guard:\n\n```go\n// standalone parseArray (line 1143) -- GUARDED\nfunc parseArray(raw []string, schemaRef *openapi3.SchemaRef) ([]any, error) {\n\tif schemaRef.Value.Items == nil || schemaRef.Value.Items.Value == nil { ... }\n\n// UrlencodedBodyDecoder top-level property loop (line 1441) -- GUARDED\nif propSchema.Value.Items == nil || propSchema.Value.Items.Value == nil { ... }\n\n// MultipartBodyDecoder (line 1587) -- GUARDED\nif valueSchema.Value.Items == nil { ... }\n```\n\nBut `urlValuesDecoder.parseArray` (line 576), which handles query-parameter and urlencoded-body array decoding, has **no** such guard:\n\n```go\nfunc (d *urlValuesDecoder) parseArray(raw []string, schemaRef *openapi3.SchemaRef) ([]any, error) {\n\tvar value []any\n\tfor i, v := range raw {\n\t\titem, err := d.parseValue(v, schemaRef.Value.Items) // Items is nil -> panic in parseValue\n```\n\n`parseValue` immediately dereferences the schema it is handed:\n\n```go\nfunc (d *urlValuesDecoder) parseValue(v string, schema *openapi3.SchemaRef) (any, error) {\n\tif len(schema.Value.AllOf) > 0 {   // schema == nil here -> nil pointer dereference\n```\n\nFor the deepObject path, `buildResObj` (line 1015) has the same gap. Its array branch recurses with `schema.Value.Items` (line 1028), which can be nil, and the recursive call dereferences it at line 1015:\n\n```go\ncase schema.Value.Type.Is(\"array\"):\n\t// ...\n\tfor i := range arr {\n\t\tr, err := buildResObj(params, mapKeys, strconv.Itoa(i), schema.Value.Items) // nil Items\n```\n\nFor the allOf body path, `UrlencodedBodyDecoder` validates only top-level `schema.Value.Properties` (line 1429-1449). But `decodeSchemaConstructs` (line 1474) recursively walks `AllOf` / `AnyOf` / `OneOf` sub-schemas and calls `decodeProperty` on their properties, which never pass through the top-level guard and reach `urlValuesDecoder.parseArray`.\n\n## Proof of Concept\n\n### Environment\n\n- kin-openapi v0.144.0 (cloned at tag `v0.144.0`, commit `f0407d5`)\n- Go 1.26.7\n- Each PoC calls `doc.Validate()` first to prove the spec is legal, then drives `openapi3filter.ValidateRequest` directly\n\n### Path 1: Query parameter array without items\n\nSpec (query param `ids` is `type: array`, no `items`), request `GET /test?ids=1&ids=2`:\n\n```\nValidate() ACCEPTED the spec (type: array with no items is legal under OAS 3.1)\nCalling ValidateRequest directly (no net/http recover)...\npanic: runtime error: invalid memory address or nil pointer dereference\n[signal 0xc0000005 code=0x0 addr=0x20 ...]\ngithub.com/getkin/kin-openapi/openapi3filter.(*urlValuesDecoder).parseValue(...)\n\treq_resp_decoder.go:605\ngithub.com/getkin/kin-openapi/openapi3filter.(*urlValuesDecoder).parseArray(...)\n\treq_resp_decoder.go:580\ngithub.com/getkin/kin-openapi/openapi3filter.(*urlValuesDecoder).DecodeArray(...)\n\treq_resp_decoder.go:569\n...\ngithub.com/getkin/kin-openapi/openapi3filter.ValidateRequest(...)\n\tvalidate_request.go:83\nexit status 2\n```\n\n### Path 2: deepObject nested array without items\n\nSpec (deepObject param `filter` with array property `tags`, no `items`), request `GET /test?filter[tags][0]=a`:\n\n```\nValidate() ACCEPTED the spec\nCalling ValidateRequest directly...\npanic: runtime error: invalid memory address or nil pointer dereference\ngithub.com/getkin/kin-openapi/openapi3filter.buildResObj(...)\n\treq_resp_decoder.go:1012\ngithub.com/getkin/kin-openapi/openapi3filter.buildResObj(...)   <- recursive call with nil Items\n\treq_resp_decoder.go:1028\ngithub.com/getkin/kin-openapi/openapi3filter.makeObject(...)\n\treq_resp_decoder.go:947\n...\nexit status 2\n```\n\n### Path 3: URL-encoded body with array inside allOf (bypasses the existing fix)\n\nSpec (urlencoded body, `allOf` sub-schema with array property `tags`, no `items`), request `POST /submit` body `tags=a&tags=b`:\n\n```\nValidate() ACCEPTED the spec\nCalling ValidateRequest directly...\npanic: runtime error: invalid memory address or nil pointer dereference\ngithub.com/getkin/kin-openapi/openapi3filter.(*urlValuesDecoder).parseValue(...)\n\treq_resp_decoder.go:605\ngithub.com/getkin/kin-openapi/openapi3filter.(*urlValuesDecoder).parseArray(...)\n\treq_resp_decoder.go:580\ngithub.com/getkin/kin-openapi/openapi3filter.(*urlValuesDecoder).DecodeArray(...)\n\treq_resp_decoder.go:569\n...\ngithub.com/getkin/kin-openapi/openapi3filter.decodeProperty(...)   <- reached via decodeSchemaConstructs (allOf walker)\n\treq_resp_decoder.go:1519\nexit status 2\n```\n\nThe `decodeProperty` frame confirms the array was reached by walking the `allOf` sub-schema, bypassing the top-level guard that the GHSA-p6wj-qrr4-pgh5 fix added.\n\n### Fix verification\n\nAdding a single nil-`items` guard to `urlValuesDecoder.parseArray` (plus one to the `buildResObj` array branch) turns all three panics into clean validation errors:\n\n```\npoc1: Returned normally, err = parameter \"ids\" in query has an error: array items schema is required for decoding\npoc2: Returned normally, err = parameter \"filter\" in query has an error: path tags: array items schema is required\npoc3: Returned normally, err = <nil>   (no panic; the allOf property is skipped by the decoder)\n```\n\nThis confirms `urlValuesDecoder.parseArray` is the shared root cause for Paths 1 and 3, and `buildResObj` for Path 2.\n\n## Impact\n\nAn unauthenticated client can trigger a deterministic nil-pointer panic in request validation with a single crafted request, against any application that validates OAS 3.1 requests with `openapi3filter` where a spec declares an array without `items`.\n\nThe severity depends on the host:\n\n| Deployment | Behavior | Availability impact |\n|------------|----------|---------------------|\n| Standard `net/http` server (validation runs in the handler goroutine) | `net/http` recovers the panic per-connection; the connection is dropped and the process survives | Per-request denial of service (A:L) |\n| Non-`net/http` hosts (e.g. fasthttp/connect adapters) or validation performed in an application-spawned goroutine | The panic is not recovered; the process crashes | Full-process denial of service (A:H) |\n\nThis was verified in both configurations: under a live `net/http` server the process survived (the panic was logged as `http: panic serving ...` and the process exited 0 at end of test), while the direct-call PoCs above crashed the process with `exit status 2`.","summary":"kin-openapi is a Go library for validating requests against OpenAPI specs. Three code paths in its openapi3filter package panic on nil items, and an earlier fix for the same class of panic was incomplete.","severity":"high","cvss":7.5,"epss":0.00335,"exploited":false,"exploited_at":null,"products":[{"name":"github.com/getkin/kin-openapi","fixed":["0.149.0"],"affected":">= 0.136.0, < 0.149.0","ecosystem":"go"}],"ecosystems":["go"],"tags":["api-validation","cwe-476","go","kin-openapi","openapi","package"],"not_affected_if":["openapi3filter-unused","version-outside-range"],"how_to_check":"- Run `go list -m github.com/getkin/kin-openapi` in the module and look for a version from `0.136.0` up to, but not including, `0.149.0`.\n- Check go.sum for `github.com/getkin/kin-openapi` at those versions.","fix":"- `github.com/getkin/kin-openapi` moves to `0.149.0`.","status":"open","published_at":"2026-10-15T17:17:07+00:00","first_seen_at":"2026-11-06T00:09:05+00:00","triaged_at":"2026-11-06T00:10:42+00:00","updated_at":"2026-11-06T00:19:08+00:00","category":"package","confidence":0.6,"triage":{"at":"2026-11-06T00:10:42Z","model":"claude-haiku-5-5","output":{"fix":"- `github.com/getkin/kin-openapi` moves to `0.149.0`.","reach":"unknown","title":"kin-openapi: nil-items input makes openapi3filter panic in Go","impact":"low","summary":"kin-openapi is a Go library for validating requests against OpenAPI specs. Three code paths in its openapi3filter package panic on nil items, and an earlier fix for the same class of panic was incomplete.","audience":"developers","category":"package","nicknames":[],"who_cares":["go","kin-openapi","openapi","api-validation"],"confidence":0.6,"fix_status":"available","needs_auth":"unknown","worst_case":"crafted request makes the Go service panic and crash","analyst_note":"","how_to_check":"- Run `go list -m github.com/getkin/kin-openapi` in the module and look for a version from `0.136.0` up to, but not including, `0.149.0`.\n- Check go.sum for `github.com/getkin/kin-openapi` at those versions.","plain_action":"","needs_analyst":false,"not_affected_if":["version-outside-range","openapi3filter-unused"],"who_is_affected":"Services that import kin-openapi's openapi3filter package to validate incoming requests against an OpenAPI schema. A crash from a panic is most likely in a service that accepts untrusted request bodies. Projects that do not import openapi3filter, or that run only on versions outside the affected range, can skip it.","user_interaction":"no","needs_special_setup":"unknown","severity_if_unknown":"medium"},"cost_usd":0.000697,"input_tokens":4298,"output_tokens":534,"severity_before":"unknown"},"analyst_status":null,"analyst_note":null,"search":"'-100353':23A,34A '-12':119C '-1449':446C '-2026':22A,30A,33A '-476':42B '-6800':31A '/getkin/kin-openapi':37A '/getkin/kin-openapi/openapi3filter.':581C '/getkin/kin-openapi/openapi3filter.(*urlvaluesdecoder).decodearray(...)':577C '/getkin/kin-openapi/openapi3filter.(*urlvaluesdecoder).parsearray(...)':573C '/getkin/kin-openapi/openapi3filter.(*urlvaluesdecoder).parsevalue(...)':569C '/test':526C '0':375C '0x0':564C '0x20':566C '0xc0000005':562C '1':165C,509C,528C '1.26.7':492C '1015':164C,388C,413C '1028':400C '1143':268C '1429':445C '1441':290C '1474':450C '1587':299C '2':174C,530C '2020':118C '3':185C '3.1':105C,544C '3ch7':27A '576':155C,307C 'accept':532C 'add':208C 'addit':141C 'addr':565C 'address':94C,556C 'allof':197C,434C,453C 'anyof':198C,454C 'api':39B 'api-valid':38B 'arr':421C 'array':106C,134C,159C,170C,180C,193C,317C,394C,417C,512C,521C,536C 'bodi':190C,316C,435C 'branch':160C,395C 'buildresobj':162C,386C,424C 'bypass':205C 'call':408C,460C,495C,545C 'case':415C 'caus':247C 'check':135C 'class':80B 'client':233C 'clone':485C 'code':63B,563C 'commit':489C 'concept':479C 'contain':178C 'crash':142C 'cve':21A,32A 'cwe':41B 'd':325C,363C 'd.parsevalue':344C 'decod':124C,318C 'decodeproperti':461C 'decodeschemaconstruct':448C 'deepobject':175C,384C 'derefer':99C,355C,381C,409C,560C 'detail':245C 'determinist':237C 'direct':507C,547C 'doc.validate':496C 'drive':505C 'earlier':75B 'encod':188C 'environ':480C 'err':343C,423C 'error':277C,333C,371C,553C 'f0407d5':490C 'first':497C 'fix':5A,76B,87C,121C,216C 'func':270C,324C,362C 'function':129C 'gap':392C 'get':525C 'ghsa':8A,25A,90C,212C,254C 'ghsa-p6wj-qrr4-pgh5':7A,89C,211C,253C 'ghsa-vrcc-3ch7-hppw':24A 'github.com':36A,568C,572C,576C,580C 'github.com/getkin/kin-openapi':35A 'github.com/getkin/kin-openapi/openapi3filter.':579C 'github.com/getkin/kin-openapi/openapi3filter.(*urlvaluesdecoder).decodearray(...)':575C 'github.com/getkin/kin-openapi/openapi3filter.(*urlvaluesdecoder).parsearray(...)':571C 'github.com/getkin/kin-openapi/openapi3filter.(*urlvaluesdecoder).parsevalue(...)':567C 'go':29A,43B,54B,264C,323C,361C,414C,491C 'guard':207C,219C,263C,269C,291C,300C,322C,473C 'hand':360C 'handl':309C 'hppw':28A 'id':518C,527C,529C 'immedi':354C 'incomplet':4A,84B 'insid':195C 'inspect':221C 'invalid':554C 'item':16A,72B,110C,173C,184C,262C,342C,347C,431C,514C,523C,539C 'json':116C 'keyword':111C 'kin':2A,45B,50B,482C 'kin-openapi':1A,44B,49B,481C 'legal':114C,503C,541C 'len':373C 'level':133C,224C,286C,442C,472C 'librari':55B 'line':163C,267C,289C,298C,306C,387C,399C,412C,444C,449C 'live':194C 'loop':288C 'mapkey':426C 'memori':555C 'method':153C 'miss':145C 'multipartbodydecod':139C,297C 'net/http':549C 'never':466C 'nil':15A,71B,97C,239C,261C,280C,282C,294C,296C,303C,349C,377C,379C,404C,430C,558C 'nil-item':14A 'nil-point':96C,238C 'oa':543C 'occur':101C 'omit':108C 'oneof':199C,455C 'openapi':3A,46B,47B,51B,60B,104C,483C 'openapi3.schemaref':275C,331C,369C 'openapi3filter':20A,67B 'openapi3filter.validaterequest':506C 'openapi3filter/req_resp_decoder.go':154C 'p6wj':9A,91C,213C,255C 'packag':48B,68B 'panic':17A,69B,82B,241C,350C,551C 'param':425C,517C 'paramet':167C,177C,312C,511C 'parsearray':128C,266C,271C,327C 'parsevalu':352C,353C,365C 'pass':467C 'patch':122C,251C 'path':18A,64B,125C,143C,204C,227C,250C,385C,436C,508C 'pgh5':11A,93C,215C,257C 'poc':494C 'pointer':98C,240C,380C,559C 'produc':235C 'proof':477C 'properti':181C,225C,287C,464C 'propschema.value.items':293C 'propschema.value.items.value':295C 'prove':499C 'qrr4':10A,92C,214C,256C 'queri':166C,176C,311C,510C,516C 'query-paramet':310C 'r':422C 'rang':340C,420C 'raw':272C,328C,341C 'reach':149C,475C 'receiv':259C 'recov':550C 'recurs':396C,407C,451C 'req_resp_decoder.go:569':578C 'req_resp_decoder.go:580':574C 'req_resp_decoder.go:605':570C 'request':58B,189C,243C,524C 'root':246C 'runtim':552C 'schema':107C,117C,202C,357C,368C,376C,458C 'schema.value.allof':374C 'schema.value.items':398C,429C 'schema.value.properties':443C 'schema.value.type.is':416C 'schemaref':274C,330C 'schemaref.value.items':279C,346C 'schemaref.value.items.value':281C 'signal':561C 'spec':61B,501C,515C,534C 'standalon':127C,265C 'strconv.itoa':427C 'string':273C,329C,367C 'sub':201C,457C 'sub-schema':200C,456C 'summari':85C 'tag':487C 'three':12A,62B,123C,140C,249C 'top':132C,223C,285C,441C,471C 'top-level':131C,222C,284C,440C,470C 'trigger':229C 'type':169C,520C,535C 'unauthent':232C 'unguard':151C,158C 'unpatch':13A 'url':187C 'url-encod':186C 'urlencod':315C 'urlencoded-bodi':314C 'urlencodedbodydecod':137C,283C,437C 'urlvaluesdecod':326C,364C 'urlvaluesdecoder.parsearray':152C,305C,476C 'v':339C,345C,366C 'v0.144.0':484C,488C 'valid':40B,57B,244C,438C,531C 'validaterequest':546C 'valu':335C 'valueschema.value.items':302C 'var':334C 'vrcc':26A 'walk':452C 'without':513C","nicknames":[],"mitigations":[],"who_affected":"Services that import kin-openapi's openapi3filter package to validate incoming requests against an OpenAPI schema. A crash from a panic is most likely in a service that accepts untrusted request bodies. Projects that do not import openapi3filter, or that run only on versions outside the affected range, can skip it.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"developers","plain_action":null,"pkeys":["githubcomgetkinkinopenapi"],"ptokens":["com","getkin","github","kin","openapi"],"labels":["apivalidation","cwe476","go","high","kinopenapi","openapi","package"],"campaign_type":null,"first_public_at":"2026-08-28T09:15:54+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","cvss_by":"GitHub","poc_count":0,"sources":[{"source":"govuln","external_id":"GO-2026-6800","url":"https://pkg.go.dev/vuln/GO-2026-6800","severity":null,"published_at":"2026-11-05T22:53:53+00:00","modified_at":"2026-11-05T22:53:53+00:00","first_seen_at":"2026-11-06T00:09:05+00:00","fetched_at":"2026-11-06T00:09:05+00:00","note":null},{"source":"nvd","external_id":"CVE-2026-100353","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-100353","severity":null,"published_at":"2026-10-15T17:17:07+00:00","modified_at":"2026-10-29T14:17:40+00:00","first_seen_at":"2026-11-06T00:19:01+00:00","fetched_at":"2026-11-06T00:19:01+00:00","note":null},{"source":"ghsa","external_id":"GHSA-vrcc-3ch7-hppw","url":"https://github.com/advisories/GHSA-vrcc-3ch7-hppw","severity":"high","published_at":"2026-10-15T20:20:47+00:00","modified_at":"2026-10-15T20:20:49+00:00","first_seen_at":"2026-11-06T00:19:08+00:00","fetched_at":"2026-11-06T00:19:08+00:00","note":null}],"documents":[{"id":81784,"url":"https://github.com/getkin/kin-openapi/commit/9814d1f2b212f3508bf52296aa9e248b2122a5a9","title":"Patch: github.com","kind":"other","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":81785,"url":"https://github.com/getkin/kin-openapi/releases/tag/v0.149.0","title":"Release notes: github.com","kind":"release","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Release notes: github.com"},{"id":81786,"url":"https://github.com/getkin/kin-openapi/security/advisories/GHSA-vrcc-3ch7-hppw","title":"Vendor advisory: github.com","kind":"vendor","source":"nvd","publisher":"vendor","text":null,"published_at":"2026-08-28T09:15:54+00:00","relation":"advisory","confidence":null,"note":"Vendor advisory: github.com"},{"id":81972,"url":"https://api.github.com/repos/getkin/kin-openapi/security-advisories/GHSA-vrcc-3ch7-hppw","title":"Maintainer's advisory: api.github.com","kind":"vendor","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":"Maintainer's advisory: api.github.com"}],"exploit_sources":[{"type":"epss","score":0.00335,"url":"https://api.first.org/data/v1/epss?cve=CVE-2026-100353"}],"notice":"Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai"}