On 2024-06-04, a critical vulnerability was disclosed affecting jq—a popular lightweight and flexible command-line JSON processor. The bug, tracked as CVE-2024-53427, affects jq versions up to 1.7.1 and can lead to stack-based buffer overflows. This article breaks down the issue, shows you what parts of the code are broken, gives you proof-of-concept, and offers mitigation advice.
What's the Problem? (Straightforward Overview)
At its heart, CVE-2024-53427 is a vulnerability rooted in decNumberCopy in decNumber.c. The function fails to properly consider that NaN (Not a Number) is interpreted as numeric in some internal operations, mainly when combined with certain JSON filters like --slurp and -. (subtraction).
This confusion can let attackers trick jq into writing outside its stack-allocated buffer—potentially allowing code execution or causing the tool to crash.
The best way to see the bug is with a minimal example. The breakdown
1. User Input Contains Special Digits/NaN: A crafted string like "1 NaN123" followed by a lot of digits.
Here, --slurp collects all input JSON values into a single array.
3. Subtraction Triggers Malformed Handling: When jq tries to subtract values, it calls its internal decNumberCopy routine. This function fails to handle NaN correctly, so it treats it as a lengthy numeric string.
Result: If the input is big enough, jq copies too much into a fixed-size buffer and writes past the end of the stack frame—classic stack overflow.
Let’s zoom in on the vulnerable code for educational purposes (excerpt simplified for clarity)
// decNumber.c
void decNumberCopy(decNumber *to, const decNumber *from) {
// ...
memcpy(to, from, sizeof(decNumber));
// ... Does not check if 'from' is a NaN or if length is safe
}
The function trusts from blindly—even if it contains special data like NaN mashed together with lots of digits. There’s no guard against an out-of-bounds copy.
`
*(Make sure to repeat the digits after "NaN" enough so the length explodes—hundreds or a few thousands)*
Why Is This So Dangerous?
- Stack Overflows: Overwriting the stack can lead to arbitrary code execution in some scenarios, especially if the binary is not compiled with modern protections (ASLR, stack canaries, etc).
- Common Usage: jq is wildly popular for scripting and automation. Automated pipelines can be pwned with a single poisoned input file.
- Silent Fails: In some contexts, jq will just crash—potentially blocking critical data processing jobs.
Original Report:
oss-security mailing list, June 4, 2024
Upstream Issue:
GitHub jq Issue #307
- Detailed Diff / Patch:
jq PR #3071
CVE Entry:
Upgrade to jq >= 1.7.2:
The jq maintainers have patched this bug. Download the new version from the jq homepage.
Temporary workaround:
Avoid using --slurp and arithmetic filters (-.) on untrusted or unexpected input content, especially if the input can contain strings like NaN with many trailing digits.
Harden jq builds:
If you must run an older jq, recompile it with stack protection (e.g., -fstack-protector-strong), and enable ASLR on your systems.
Conclusion
CVE-2024-53427 is a classic and dangerous memory safety issue affecting jq, a common tool in many data processing stacks. It highlights the risks of subtle bugs in numeric code—especially when parsing data mixed with special values like NaN.
Be cautious with complex input and filters until you're sure your jq is safe.
*Stay safe, and always validate and sanitize your data pipelines!*
Timeline
Published on: 02/26/2025 16:15:16 UTC
Last modified on: 03/28/2025 17:15:27 UTC