Proof Portal
jsonparser
ProbeLabsviewing a historical runEmpty-string key path component panics (hazard-sweep finding)
This defect has been fixed and verified.
Description
The issue as recorded. A plain-language impact summary hasn't been written for this finding yet.
A blind discovery pass (hazard-sweep for the panic_free_input_handling obligation class) found that passing "" as a path component to any of Get, GetString, GetInt, GetFloat, GetBoolean, GetUnsafeString, EachKey, Set, or Delete crashed the goroutine with runtime error: index out of range [0] with length 0 because the path-side code indexed keys[i][0] / p[level][0] without first checking that the component string was non-empty.
Verified reproducers (pre-fix): Get([]byte([1,2,3]), "") // PANIC parser.go:409 (searchKeys) Get([]byte({"a":[1]}), "a", "") // PANIC parser.go:409 (searchKeys) EachKey([]byte([1,2,3]), cb, []string{""})// PANIC parser.go:614 Set([]byte({}), []byte("v"), "") // PANIC parser.go:719 (createInsertComponent)
The root cause is identical in shape to the OSS-Fuzz Delete panic fixed earlier: a caller-controlled byte reaches an unguarded slice index. The fix pattern (len(...) > 0 && ...[0] == "[") already existed in Delete and has now been applied to all seven remaining dereference sites. The hazard is FIXED in this same change; the linked KnownIssue KI-260726-001 records the fixed state and the regression tests in empty_key_path_test.go.
Affected requirements
The requirement(s) this issue violates — click through to the spec.
Severity, explained
Why this is rated the way it is — and the scoring signals behind the rating (each ⓘ explains the term).
- risk area
- Security Behavior
Where it is
The code this defect touches — peek any of these files inline to see the exact spot.
Root cause
What actually went wrong underneath — how it is classified, and the coverage gap that let it slip through.
The security/hazard-sweep role identified the same panic bug class as the OSS-Fuzz Delete panic (caller-controlled input -> unguarded `[]` index), but on the path side. Every fuzz harness hardcodes non-empty path strings, so the empty-string key component partition was never exercised. Six unguarded `keys[i][0]` / `p[level][0]` dereference sites in searchKeys, EachKey, createInsertComponent, and calcAllocateSpace panicked with `runtime error: index out of range [0] with length 0` when a caller passed an empty-string path component. The correct `len(...) > 0` guard pattern already existed in Delete (parser.go:835) but was not applied consistently to the other dereference sites.
Disposition: Covered by a requirement
Proof it's fixed
The tests, tightened requirements and new obligations that prove this defect is gone — and can't quietly return.
Covered by a requirement.
Blast radius
If you touch this issue, what else may need re-checking — the requirements it affects and the code and tests that hang off them. Historical view: authored trace links only — automatically derived links aren't reconstructible for past runs.
Touch this finding and you re-check 5 requirements · 5 code files · 23 tests.
- parser.go
- fuzz.go
- append.go
- escape.go
- path_compiler.go
- deep_spec_test.go
- empty_key_path_test.go
- mcdc_spec_witnesses_test.go
- obligation_evidence_test.go
- parser_test.go
- sys_req_110_111_witness_test.go
- array_each_err_test.go
- coverage_closure_test.go
- and 15 more
Per-requirement evidence
For each requirement this finding touches: the implementing code, verifying tests, and proof obligations that discharge it.
Per-requirement evidence
For each requirement this finding touches: the implementing code, verifying tests, and proof obligations that discharge it.
Change history
Every recorded revision of this finding's source file — when it was added, edited, or re-classified, with the diff for each change.
Discussions
Discuss this with the proof team. Nothing changes in your audit automatically — you open a request and a staff member records any outcome inside the thread.