Mar 18, 2026·6 min read·4 visits
Unvalidated offset calculations in jsonparser's Delete function cause a runtime panic with malformed JSON, enabling Denial of Service attacks.
A denial-of-service vulnerability exists in github.com/buger/jsonparser up to version 1.1.1. The Delete function fails to validate offset bounds when processing malformed JSON, leading to a runtime panic and immediate process termination.
The github.com/buger/jsonparser package is a high-performance, zero-allocation JSON parsing library for Go. The library prioritizes performance by relying heavily on manual byte offset arithmetic rather than standard Go structures. A vulnerability exists in the Delete() function, which is responsible for removing specific keys from a JSON byte slice.
When the Delete() function processes specific malformed JSON fragments, the internal state machine calculates an invalid deletion boundary. The resulting offset computation produces a negative integer. This value is subsequently used as a slice index without prior bounds checking.
Go strictly enforces slice bounds at runtime. Attempting to slice an array or slice with a negative index triggers an immediate runtime error: slice bounds out of range panic. In Go applications, an unhandled panic terminates the executing process entirely, leading to a Denial of Service (DoS) condition.
The vulnerability stems from improper validation of calculated array indices within the Delete() function located in parser.go. The parser implements a custom state machine to traverse JSON structures and identify the start and end byte offsets of a requested key.
During the parsing of a structurally invalid JSON sequence, such as a missing closing brace or an isolated string missing a value separator, the parser misinterprets the structural boundaries. The logic responsible for calculating the end offset of the targeted key subtracts an incorrect length from the current position. This arithmetic error results in an offset variable value of -1.
At parser.go:729 in version 1.1.1, the function returns a newly constructed slice representing the JSON data without the deleted key. The operation executes return data[offset:]. Because offset equals -1, the Go runtime detects an out-of-bounds slice operation and panics. The defect occurs because the library trusts its internal parsing loop to yield valid, positive boundaries without performing a defensive bounds check before the slice operation.
The vulnerable code path exists at the termination of the Delete() function. The implementation incorrectly assumes that all offsets generated by the parsing loop are mathematically valid for the provided byte slice.
// Vulnerable code in parser.go (version 1.1.1)
// The offset variable is derived from earlier calculations based on malformed input.
return data[offset:]The required fix must explicitly validate the bounds of the offset variable before utilizing it in a slice operation. If the calculation yields a negative value, the function should return the original data unmodified, or handle the error gracefully without triggering a runtime panic.
// Suggested manual mitigation for parser.go:729
if offset < 0 {
return data
}
return data[offset:]This exact vulnerability pattern follows a similar historical flaw in the same function. CVE-2020-10675 involved an infinite loop within Delete() due to mishandled state tracking. The current issue demonstrates that while the infinite loop was patched in version 1.1.0, the broader boundary validation logic within Delete() remains incomplete.
Exploitation requires the attacker to supply a crafted, malformed JSON payload to an endpoint that processes untrusted input using jsonparser.Delete(). No authentication or specific network position is required beyond standard access to the vulnerable endpoint.
The proof-of-concept constructs a malformed JSON byte slice: "0":"0":. This string consists of key-value pairs lacking the standard JSON enclosing brackets and trailing structure. When the Delete() function attempts to remove the key "0", the internal state machine calculates the deletion boundary as -1.
package main
import (
"fmt"
"github.com/buger/jsonparser"
)
func main() {
data := []byte(`"0":"0":`)
result := jsonparser.Delete(data, "0")
fmt.Println(string(result))
}Execution of this payload results in a deterministic crash. The Go runtime prints the panic stack trace: panic: runtime error: slice bounds out of range [-1:], specifying the exact file and line number (parser.go:729) before exiting with a non-zero status code.
The vulnerability carries a CVSS v3.1 base score of 7.5 (High), reflecting a severe impact on availability. The CVSS vector is CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H. The defect does not compromise confidentiality or integrity, as memory is not leaked or corrupted before the process terminates.
The concrete security impact is a highly reliable application crash. Go web servers commonly handle distinct requests in separate goroutines. While individual goroutine panics can be caught using recover(), many applications do not implement global recovery middleware. In these environments, an unhandled panic in a single goroutine terminates the entire parent process.
This behavior is specifically impactful for systems designed for high-throughput processing, such as API gateways, logging agents, and data ingestion pipelines. These applications often select jsonparser specifically to bypass standard parsing overhead. A single malformed request from an unauthenticated attacker can effectively disable the entire service, requiring external process supervisors to restart it, causing service interruption and dropped traffic.
The following diagram illustrates the execution flow from input ingestion to process termination.
As of March 2026, there is no official patched release for github.com/buger/jsonparser. Version 1.1.1 remains the latest release and is vulnerable to this DoS condition. Organizations must implement compensating controls to prevent exploitation.
The most effective mitigation is implementing input validation before invoking the Delete() function. Developers should execute json.Valid() from the standard library to ensure structural integrity of the input. However, this approach negates the primary performance benefit of using a zero-allocation parser, as standard library validation incurs overhead.
Alternatively, Go applications must implement global panic recovery. Developers should wrap HTTP handlers or processing loops in middleware that utilizes the recover() function. This ensures that a panic within a single request context is caught, logged, and isolated, preventing the termination of the main application process. Organizations with strict performance requirements can implement the manual bounds check directly in a vendored copy of the library.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
jsonparser buger | <= 1.1.1 | - |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-129 |
| Attack Vector | Network (Remote) |
| CVSS v3.1 | 7.5 (High) |
| Impact | Denial of Service (Process Termination) |
| Exploit Status | Proof of Concept (PoC) Available |
| KEV Status | Not Listed |
The product uses untrusted input as a calculation for an array index without proper validation, resulting in a negative index.