GHSA-rj39-cv6w-8wv7

Suggest an improvement
Source
https://github.com/advisories/GHSA-rj39-cv6w-8wv7
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-rj39-cv6w-8wv7/GHSA-rj39-cv6w-8wv7.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-rj39-cv6w-8wv7
Aliases
Published
2026-10-15T20:20:27Z
Modified
2026-10-15T20:30:11Z
Severity
  • 7.5 (High) CVSS_V3 - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H CVSS Calculator
Summary
kin-openapi: YAML NaN/Inf Values Bypass Built-in Guards and Panic via OAS 3.1 Validation Path
Details

Summary

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).

Details

Root Cause

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.

Proof of Concept

Environment

  • kin-openapi v0.144.0 (tag v0.144.0, commit f0407d5)
  • santhosh-tekuri/jsonschema/v6 v6.0.2 (transitive dep)
  • Go 1.26.7

Spec

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 }

Trigger

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 stack trace (confirms exact chain)

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/v6@v6.0.2/validator.go:525
github.com/santhosh-tekuri/jsonschema/v6.(*validator).validate(...)
    .../jsonschema/v6@v6.0.2/validator.go:168
github.com/santhosh-tekuri/jsonschema/v6.(*Schema).validate(...)
    .../jsonschema/v6@v6.0.2/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

net/http behavior (severity nuance)

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.

Fix verification

Upgrading only the transitive dependency to jsonschema/v6@v6.0.3 (via go get github.com/santhosh-tekuri/jsonschema/v6@v6.0.3) 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.

Why This Is a Vulnerability, Not by Design

  • The library explicitly refuses NaN/Inf in its own visitor (ErrSchemaInputNaN / ErrSchemaInputInf at schema.go:1968). The stated policy is: these values are not allowed.
  • The OAS 3.1 dispatch (useJSONSchema2020) simply omits the same guard — a coding gap, not a design decision.
  • Upstream jsonschema/v6 v6.0.3 fixes the same case as a bug. Two independent code owners agree it should not panic.
  • The trigger is a single HTTP request body an unauthenticated client can send. There is no legitimate content-authoring reason to submit .nan / .inf as a numeric field.

Impact

  • Per-request denial of service (net/http hosts). Every crafted request kills its own connection with zero attacker cost. Sustained flooding degrades service reliability and log noise.
  • Full-process denial of service (non-net/http hosts or goroutine-spawned validation). No net/http recovery wrapper is present; the whole process crashes on a single request.
  • Attack surface is any OAS 3.1 API that accepts YAML bodies with numeric constraints. These constraints (minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf) are common on any numeric field with a range.
Database specific
{
    "cwe_ids":  [
        "CWE-754"
    ],
    "github_reviewed":  true,
    "github_reviewed_at":  "2026-10-15T20:20:27Z",
    "nvd_published_at":  "2026-10-15T16:17:31Z",
    "severity":  "HIGH"
}
References

Affected packages

Go / github.com/getkin/kin-openapi

Package

Name
github.com/getkin/kin-openapi
View open source insights on deps.dev
Purl
pkg:golang/github.com/getkin/kin-openapi

Affected ranges

Type
SEMVER
Events
Introduced
0 Unknown introduced version / All previous versions are affected
Fixed
0.148.0

Database specific

source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-rj39-cv6w-8wv7/GHSA-rj39-cv6w-8wv7.json"