
Loading

Loading
We use strictly necessary cookies to run this site, and analytics cookies to understand how it's used. See our Privacy Policy for details.
A GitHub-reviewed security advisory, not necessarily under active exploitation the way our CISA KEV advisories are, but a real, disclosed vulnerability in an open-source dependency.
Affected packages
Vulnerable: < 0.148.0
Patched in 0.148.0
Details
kin-openapi guards against NaN and Inf values in its built-in schema visitor (visitJSON) by returning ErrSchemaInputNaN / ErrSchemaInputInf when a float64 input violates those constraints. For OAS 3.1 specs, however, Schema.VisitJSON routes through useJSONSchema2020, which hands the value directly to santhosh-tekuri/jsonschema/v6 v6.0.2 without applying the same guard.
Inside jsonschema/v6 v6.0.2, numValidate builds a *big.Rat from the input via big.Rat.SetString(fmt.Sprintf("%v", v)). For NaN/Inf this parse fails silently and returns nil. numValidate then dereferences the nil *big.Rat (in math/big.(*Rat).Cmp), producing a Go runtime panic.
An attacker delivers this by sending an HTTP request with Content-Type: application/yaml (or application/x-yaml) and a YAML body containing .nan, .inf, or -.inf. The YamlBodyDecoder decodes those tokens into math.NaN() / math.Inf(±1) (standard YAML 1.2 behavior), and they propagate to the unguarded useJSONSchema2020 path whenever the schema declares a numeric constraint (minimum, maximum, exclusiveMinimum, exclusiveMaximum, or multipleOf).
The built-in visitor visitJSON at openapi3/schema.go:1968 guards NaN/Inf explicitly:
case float64:
if math.IsNaN(value) {
return ErrSchemaInputNaN
}
if math.IsInf(value, 0) {
return ErrSchemaInputInf
}
For OAS 3.1 specs, VisitJSON dispatches to useJSONSchema2020 (openapi3/schema_jsonschema_validator.go:204), which contains no such guard:
func (schema *Schema) useJSONSchema2020(settings *schemaValidationSettings, value any) error {
validator, err := newJSONSchemaValidator(schema)
if err != nil {
return schema.visitJSON(settings, value)
}
return validator.validate(value) // value handed straight through
}
jsonSchemaValidator.validate calls jsonschema/v6.Schema.Validate (line 146), which reaches numValidate in v6.0.2. There, big.Rat.SetString(fmt.Sprintf("%v", v)) returns (nil, false) for NaN/Inf, and the code dereferences the nil *big.Rat in Rat.Cmp, causing the panic.
v0.144.0, commit f0407d5)Minimal OAS 3.1 spec (spec.yaml) declaring a YAML body with a numeric constraint:
openapi: '3.1.0'
info: { title: Test, version: '1.0' }
paths:
/test:
post:
requestBody:
required: true
content:
application/yaml:
schema:
type: number
minimum: 0
responses:
'200': { description: OK }
A single POST /test with Content-Type: application/yaml and body .nan, .inf, or -.inf. All three variants panic:
=== RUN TestNaNInf
[nan] PANIC (confirms vuln): runtime error: invalid memory address or nil pointer dereference
[inf] PANIC (confirms vuln): runtime error: invalid memory address or nil pointer dereference
[neginf] PANIC (confirms vuln): runtime error: invalid memory address or nil pointer dereference
panic: runtime error: invalid memory address or nil pointer dereference
math/big.(*Rat).Cmp(0x0, ...) <- nil *big.Rat dereferenced
C:/Program Files/Go/src/math/big/rat.go:492
github.com/santhosh-tekuri/jsonschema/v6.(*validator).numValidate(...)
.../jsonschema/[email protected]/validator.go:525
github.com/santhosh-tekuri/jsonschema/v6.(*validator).validate(...)
.../jsonschema/[email protected]/validator.go:168
github.com/santhosh-tekuri/jsonschema/v6.(*Schema).validate(...)
.../jsonschema/[email protected]/validator.go:34
github.com/getkin/kin-openapi/openapi3.(*jsonSchemaValidator).validate(...)
openapi3/schema_jsonschema_validator.go:146
github.com/getkin/kin-openapi/openapi3.(*Schema).useJSONSchema2020(...) <- MISSING NaN/Inf guard
openapi3/schema_jsonschema_validator.go:211
github.com/getkin/kin-openapi/openapi3.(*Schema).VisitJSON(...)
openapi3/schema.go:1946
github.com/getkin/kin-openapi/openapi3filter.ValidateRequestBody(...)
openapi3filter/validate_request.go:364
github.com/getkin/kin-openapi/openapi3filter.ValidateRequest(...)
openapi3filter/validate_request.go:96
Behind a standard net/http server, the panic is recovered per-connection. The client sees a dropped connection; the server process continues:
Sending POST /test body=.nan against real net/http server...
2026/08/25 http: panic serving 127.0.0.1:40625: runtime error: invalid memory address or nil pointer dereference
CLIENT ERROR (connection dropped): Post ".../test": EOF
Process still alive after request: true
This is a recoverable panic, unlike the recursion finding. recover() catches it (verified by capturing the panic value in a defer in the same goroutine). Non-net/http hosts or validation performed in an application-spawned goroutine are not covered by that recovery and would experience a full-process crash.
Upgrading only the transitive dependency to jsonschema/[email protected] (via go get github.com/santhosh-tekuri/jsonschema/[email protected]) eliminates the panic entirely; all three payloads return a clean validation error:
[nan] Returned normally, err = request body has an error: doesn't match schema: validation failed due to: at '': invalid jsonType float64
[inf] Returned normally, err = request body has an error: doesn't match schema: validation failed due to: at '': invalid jsonType float64
[neginf] Returned normally, err = request body has an error: doesn't match schema: validation failed due to: at '': invalid jsonType float64
This confirms the upstream jsonschema/v6 v6.0.3 release treats the NaN/Inf case as a bug and fixes it at the source. It also confirms useJSONSchema2020 is the reachable path: patching only the transitive dep removes the panic without touching kin-openapi code.
ErrSchemaInputNaN / ErrSchemaInputInf at schema.go:1968). The stated policy is: these values are not allowed.useJSONSchema2020) simply omits the same guard — a coding gap, not a design decision.jsonschema/v6 v6.0.3 fixes the same case as a bug. Two independent code owners agree it should not panic..nan / .inf as a numeric field.net/http recovery wrapper is present; the whole process crashes on a single request.minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf) are common on any numeric field with a range.Talk to us about this
Find out whether this dependency (or others like it) is actually reachable in your codebase.
Get help patching, or building dependency-scanning into your pipeline going forward.
A secure code review or supply chain review finds this before an advisory does.