Proof Portal
jsonparser
ProbeLabs36 findings · 123 requirementsunescapeToUTF8Config length guard off-by-one — OOB panic reading in[1] on a lone trailing backslash
High-severity issue, currently open.
Introduced
When and where this issue first entered the codebase — the commit it traces back to.
Affected requirements
The requirement(s) this issue violates — click through to the spec.
What this means for you
Plain-language impact — what this issue could mean for your users and your system, before any of the technical detail.
A single lone trailing backslash in attacker-controlled JSON crashes the consuming service (denial of service) instead of surfacing a MalformedStringEscapeError. Intentional demo defect on the proof-demo showcase branch; never shipped.
Reachable through any Unescape/ParseString/Get* call on attacker-controlled JSON whose string value ends in an unpaired trailing backslash; no special build tags or API options required.
Technical description
unescapeToUTF8Config (escape.go) consumes a backslash escape by reading the escape byte at in[1] after a minimum-length guard. On the proof-demo showcase branch that guard was weakened from `if len(in) < 2` to `if len(in) < 1` (escape.go:194), so a single-byte input `\` passes the check and the escape switch reads in[1] one byte past the end of the slice — a CWE-125 Out-of-bounds Read reachable via a lone trailing backslash. The Go runtime converts the read into an index-out-of-range panic, aborting the parse. Intentional demo defect on the proof-demo showcase branch; never shipped.
Severity, explained
Why this is rated the way it is — and the scoring signals behind the rating (each ⓘ explains the term).
- why this rating
- Reproducer-confirmed
- risk area
- Availability
- CVSS
- CVSS 7.5· Highv3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - CVE surface
- Likely
Where it is
The code the issue lives in — peek the affected function inline to see it in context.
- unescapeToUTF8Config
How it's proven
The reproducer — an actual test that drives the real code and shows the issue happening. Run it yourself, or peek the test and the source it covers.
go test -run TestDemoKI6 -count=1 .
Reproduction steps
Technical steps for your engineers to confirm the issue by hand.
- Check out the proof-demo showcase branch and build the package.
- Call jsonparser.GetString on a value that ends in a lone backslash — or run: go test -run TestDemoKI6 -count=1 .
- Observe an index-out-of-range panic from unescapeToUTF8Config rather than MalformedStringEscapeError.
go test -run TestDemoKI6 -count=1 . go test ./... -count=1
How it can be triggered
The input or condition that sets this issue off.
a JSON string value ending in a lone, dangling backslash, e.g. {"k":"\"}
What protects you, and the fix
What limits your exposure today, and the planned remediation.
What protects you now
Bound untrusted input size and recover/validate around parse calls until the length guard is restored; reject strings with dangling escapes before handing them to the parser.
The fix
Restore the 2-byte minimum-length guard in unescapeToUTF8Config (escape.go:194, `if len(in) < 1` -> `if len(in) < 2`) so a lone trailing backslash returns (-1, -1) and the caller surfaces MalformedStringEscapeError. Closes CWE-125 Out-of-bounds Read; cf. RFC 8259 section 7.
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.
Touch this finding and you re-check 2 requirements · 1 code files · 3 tests.
- parser.go
- deep_spec_test.go
- mcdc_spec_witnesses_test.go
- parser_test.go
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.
Evidence trail
The raw evidence manifests behind this finding — superseded by the resolved reproducer above, kept here for traceability.
Evidence trail
The raw evidence manifests behind this finding — superseded by the resolved reproducer above, kept here for traceability.
- proof/evidence/KI-6-reproducer.yaml
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.