Introduction
The go.mod file in any Go project is deceptively simple — a list of module names and version pins. But each line is a trust decision. When the Trivy scanner flagged github.com/buger/jsonparser v1.1.1 in this project's dependency tree, it revealed that a single indirect dependency version pin was exposing every JSON-parsing code path to a potential Denial of Service attack.
This post walks through exactly what CVE-2026-32285 is, how the vulnerable version of buger/jsonparser could be exploited against a running Go service, and what the one-line go.mod change actually does to close the door.
The Vulnerability Explained
What is buger/jsonparser and why is it here?
github.com/buger/jsonparser is a high-performance, zero-allocation JSON parsing library for Go. It is widely used as a transitive dependency — meaning your code may not call it directly, but another library in your dependency graph does. In this project it appears as an // indirect dependency:
// go.mod (before fix)
github.com/buger/jsonparser v1.1.1 // indirect
The // indirect comment is Go's way of saying: "We don't import this ourselves, but something we depend on does." That does not mean the vulnerability is unreachable — it means the attack surface is wherever the parent dependency passes untrusted data through jsonparser.
CVE-2026-32285: Denial of Service via Malformed JSON
In buger/jsonparser v1.1.1, certain sequences of malformed or truncated JSON bytes are not handled defensively. When the parser encounters these sequences, it can:
- Panic — causing the Go runtime to crash the goroutine (or the whole process if not recovered)
- Loop or stall — consuming CPU in an uncontrolled way (CWE-400: Uncontrolled Resource Consumption)
The root cause is insufficient bounds-checking and error-path handling inside the library's byte-level parsing routines when input does not conform to expected JSON structure.
A Concrete Attack Scenario
Consider a Go service that accepts JSON payloads over HTTP — a REST API endpoint, a webhook receiver, or a message queue consumer. Internally, one of its dependencies uses buger/jsonparser to extract fields from those payloads.
An attacker sends a crafted HTTP request body:
POST /api/ingest HTTP/1.1
Content-Type: application/json
{"key": "\x00\xff\xfe
This truncated, byte-mangled payload is valid enough to pass a naive Content-Type check but malformed enough to trigger the vulnerable code path inside buger/jsonparser v1.1.1. The result: the parsing goroutine panics or stalls. With enough concurrent requests, the service becomes unavailable — a classic application-layer DoS.
Because buger/jsonparser is an indirect dependency, developers often don't realize their service is exposed until a scanner like Trivy surfaces it.
The Fix
The fix is surgical and low-risk: bump github.com/buger/jsonparser from v1.1.1 to v1.1.2 in both go.mod and go.sum.
go.mod Change
- github.com/buger/jsonparser v1.1.1 // indirect
+ github.com/buger/jsonparser v1.1.2 // indirect
v1.1.2 patches the malformed-input handling so that the parser returns a proper error instead of panicking or looping. Valid JSON inputs are completely unaffected — the change only tightens behavior on the invalid-input path.
go.sum Change
+ github.com/buger/jsonparser v1.1.2 h1:frqHqw7otoVbk5M8LlE/L7HTnIq2v9RX6EJ48i9AxJk=
+ github.com/buger/jsonparser v1.1.2/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
The go.sum file stores cryptographic hashes (SHA-256) of every module version that enters the build. Adding the v1.1.2 hashes here is mandatory: Go's module system will refuse to use a version whose hash is not recorded in go.sum, preventing supply-chain tampering. The old v1.1.1 entries remain in go.sum for historical auditability but are no longer selected by the build.
Why Two Files?
| File | Role | What Changed |
|---|---|---|
go.mod |
Declares the minimum required version | Version pin updated from v1.1.1 → v1.1.2 |
go.sum |
Cryptographic integrity ledger | Hash entries for v1.1.2 appended |
Both changes are required. Updating only go.mod without go.sum would cause go build to fail with a checksum mismatch error.
Key Takeaways
- Indirect Go dependencies carry real CVE risk. The
// indirectlabel ingo.moddoes not mean "safe to ignore" — it means your attack surface includes code you didn't write and may not have reviewed. go.sumis a security control, not just bookkeeping. The hash entries forv1.1.2ensure the exact patched bytes are used at build time; never skip updatinggo.sumwhen changinggo.mod.- Malformed JSON DoS is a realistic threat for any HTTP-facing Go service. If your service accepts JSON from untrusted clients, the parsing library version matters as much as your own input-validation logic.
govulncheckcan tell you if the vulnerable symbol is actually reachable, saving triage time when you have many flagged indirect dependencies.- A one-line version bump in
go.modclosed a critical availability gap — the cost of the fix was near zero; the cost of ignoring it could have been a production outage.
How Orbis AppSec Detected This
- Source: Any HTTP endpoint or message consumer in the application that accepts untrusted JSON payloads and routes them through a dependency that calls
buger/jsonparser. - Sink: The byte-parsing routines inside
github.com/buger/jsonparser v1.1.1that process raw JSON bytes without adequate bounds-checking on malformed input sequences. - Missing control: No version constraint in
go.modrequired the patchedv1.1.2release; the project was locked to the vulnerablev1.1.1. - CWE: CWE-400 — Uncontrolled Resource Consumption.
- Fix: Updated
go.modto requiregithub.com/buger/jsonparser v1.1.2and added the corresponding cryptographic checksums togo.sum.
Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.
Conclusion
CVE-2026-32285 is a textbook example of why dependency hygiene is a security practice, not just a maintenance chore. The vulnerable code wasn't written by the application team — it lived two layers deep in the dependency graph — but it was fully capable of taking down the service. The fix required changing exactly one version string in go.mod and adding two lines to go.sum. That's a remarkably low cost for closing an availability risk that could have manifested as a production incident.
The broader lesson: treat every line in go.mod as a security decision. Automate scanning, enforce version floors in CI, and don't let // indirect lull you into a false sense of safety.