Where
-Infinity
0

Vendor Risk Score

See how jqlang compares to other vendors in security performance

View Risk Score →
Severity
6.1
Null Pointer Dereference
AV:L/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:H

jq is a command-line JSON processor. Prior to version 1.8.2, the strindices builtin in jq's src/builtin.c passes its arguments directly to jvstringindexes() without verifying they are strings, and jvstringindexes() in src/jv.c relies solely on assert() checks that are stripped in release builds compiled with -DNDEBUG. This allows an attacker to crash jq trivially with input like strindices(0), and by crafting a numeric value whose IEEE-754 bit pattern maps to a chosen pointer, achieve a controlled pointer dereference and limited memory read/probe primitive. Any deployment that evaluates untrusted jq filters against a release build is vulnerable. This issue has been patched in commit fdf8ef0f0810e3d365cdd5160de43db46f57ed03, which is part of version 1.8.2.

1 / 2
Source: MITRE
First published (updated )
Severity
6.5
Integer Overflow
AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:L

jq has signed integer overflow in jv.c:jvparraywrite

1 / 2
Source: Microsoft
First published (updated )
Severity
7.7
EPSS
0.06%
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:P/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

AddressSanitizer: stack-buffer-overflow in jqfuzzexecute (jvstringvfmt)

1 / 2
Source: Microsoft
First published (updated )
Severity
6.9
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:N/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

jq is a command-line JSON processor. In commits before 2f09060afab23fe9390cce7cb860b10416e1bf5f, the jvparsesized() API in libjq accepts a counted buffer with an explicit length parameter, but its error-handling path formats the input buffer using %s in jvstringfmt(), which reads until a NUL terminator is found rather than respecting the caller-supplied length. This means that when malformed JSON is passed in a non-NUL-terminated buffer, the error construction logic performs an out-of-bounds read past the end of the buffer. The vulnerability is reachable by any libjq consumer calling jvparsesized() with untrusted input, and depending on memory layout, can result in memory disclosure or process termination. The issue has been patched in commit 2f09060afab23fe9390cce7cb860b10416e1bf5f.

1 / 2
Source: MITRE
First published (updated )
Severity
8.1
Buffer Overflow
AV:L/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H

decNumberCopy in decNumber.c in jq through 1.7.1 does not properly consider that NaN is interpreted as numeric, which has a resultant stack-based buffer overflow and out-of-bounds write, as demonstrated by use of --slurp with subtraction, such as a filter of .-. when the input has a certain form of digit string with NaN (e.g., "1 NaN123" immediately followed by many more digits).

First published (updated )
Severity
6.8
CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

jq is a command-line JSON processor. Prior to 1.8.2, comparing two sufficiently deeply nested arrays with the == operator exhausts the C stack on jq's ordinary command-line surface, resulting in denial of service via stack exhaustion (uncontrolled recursion). The crash occurs in jq's recursive structural comparison code, with the recursion repeating through jvparrayequal() and jvequal() in src/jv.c when comparing deeply nested arrays; a nearby sort comparator path through jvcmp() in src/jvaux.c overflows the stack at a larger nesting depth from the same missing recursion guard. Anyone running jq comparisons on attacker-controlled deeply nested JSON values, or embedding jq in a context where untrusted data can reach the == comparison path, is affected. This vulnerability is fixed in 1.8.2.

1 / 2
Source: NVD
First published (updated )
Severity
7.1
AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:H

jq --rawfile invalid-state reuse after String too long causes heap-buffer-overflow

1 / 2
Source: Microsoft
First published (updated )
Severity
4.8
EPSS
0.04%
AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L/E:P/RL:X/RC:R

A vulnerability was determined in jqlang jq up to 1.6. Impacted is the function runjqtests of the file jqtest.c of the component JSON Parser. Executing manipulation can lead to reachable assertion. The attack requires local access. The exploit has been publicly disclosed and may be utilized. Other versions might be affected as well.

1 / 2
Source: MITRE
First published (updated )
Severity
6.9
Integer Overflow, Buffer Overflow
CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

jq is a command-line JSON processor. Prior to 1.8.2, on 32bit system, jvpstringappend has a chance of integer/multiple overflowing and then causing a massive buffer overrun. This vulnerability is fixed in 1.8.2.

First published (updated )
Severity
5.5
AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:N

jq is a command-line JSON processor. In 1.8.1 and earlier, Top-level jq programs loaded from a file with -f are truncated at the first embedded NUL byte on current upstream HEAD. A crafted filter file such as . followed by \x00 and arbitrary suffix compiles and executes as only the prefix before the NUL. This leaves jq with a post-CVE-2026-33948 prefix/full-buffer mismatch on the compilation path even though the JSON parser path has already been fixed.

1 / 2
Source: MITRE
First published (updated )
Severity
5.4
CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:P/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

jq is a command-line JSON processor. In 1.8.2rc1 and earlier, the ordinary module loader recurses without cycle detection when two otherwise valid modules include each other.

1 / 2
Source: MITRE
First published (updated )
Severity
5.4
CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:P/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

jq is a command-line JSON processor. In 1.8.1 and earlier, jvcontains recurses into nested arrays/objects with no depth limit. With a sufficiently nested input structure (built programmatically with reduce, since the JSON parser caps at depth 10000), the C stack is exhausted.

1 / 2
Source: MITRE
First published (updated )
Severity
4.4
Input Validation
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N

jq is a command-line JSON processor. In 1.8.1 and earlier, jq accepts embedded NUL bytes in import paths at the jq-language level, but later resolves those paths through C string operations during module and data-file lookup. This creates a mismatch between the logical import string that policy or audit code may validate and the on-disk path that jq actually opens.

1 / 2
Source: NVD
First published (updated )
Severity
6.2
AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

jq is a command-line JSON processor. In 1.8.1 and earlier, unbounded recursion in jvobjectmergerecursive() allows a crafted jq program to crash the process with a segfault. The function is reachable through the operator when both operands are objects.

1 / 2
Source: MITRE
First published (updated )
Severity
6.4
Integer Overflow
CVSS:4.0/AV:L/AC:H/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:P/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

jq is a command-line JSON processor. In 1.8.1 and earlier, the jq bytecode VM's data stack tracks its allocation size in a signed int. When the stack grows beyond ≈1 GiB (via deeply nested generator forks), the doubling arithmetic overflows. The wrapped value is passed to realloc and then used for a memmove with attacker-influenced offsets.

1 / 2
Source: MITRE
First published (updated )
Severity
6.2
Integer Overflow
AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

jq is a command-line JSON processor. In 1.8.1 and earlier, when decNumberFromString is given a number literal of INTMAX-1 (2147483646) digits, the D2U() macro overflows during signed-int arithmetic. The wrapped negative value bypasses the heap-allocation size check, causes the function to use a 30-byte stack buffer, and then writes ≈715 million 16-bit units (≈1.4 GiB) at an offset 1.43 GiB below the stack frame. The written content is fully attacker-controlled (the parsed decimal digits, packed 3-per-unit).

First published (updated )
Severity
2.9
Input Validation
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:P/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

jq is a command-line JSON processor. Commits before 6374ae0bcdfe33a18eb0ae6db28493b1f34a0a5b contain a vulnerability where CLI input parsing allows validation bypass via embedded NUL bytes. When reading JSON from files or stdin, jq uses strlen() to determine buffer length instead of the actual byte count from fgets(), causing it to truncate input at the first NUL byte and parse only the preceding prefix. This enables an attacker to craft input with a benign JSON prefix before a NUL byte followed by malicious trailing data, where jq validates only the prefix as valid JSON while silently discarding the suffix. Workflows relying on jq to validate untrusted JSON before forwarding it to downstream consumers are susceptible to parser differential attacks, as those consumers may process the full input including the malicious trailing bytes. This issue has been patched by commit 6374ae0bcdfe33a18eb0ae6db28493b1f34a0a5b.

1 / 2
Source: MITRE
First published (updated )
Severity
6.2
AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

jq is a command-line JSON processor. In versions 1.8.1 and below, functions jvsetpath(), jvgetpath(), and delpathssorted() in jq's src/jvaux.c use unbounded recursion whose depth is controlled by the length of a caller-supplied path array, with no depth limit enforced. An attacker can supply a JSON document containing a flat array of ~65,000 integers (~200 KB) that, when used as a path argument by a trusted jq filter, exhausts the C call stack and crashes the process with a segmentation fault (SIGSEGV). This bypass works because the existing MAXPARSINGDEPTH (10,000) limit only protects the JSON parser, not runtime path operations where arrays can be programmatically constructed to arbitrary lengths. The impact is denial of service (unrecoverable crash) affecting any application or service that processes untrusted JSON input through jq's setpath, getpath, or delpaths builtins. This issue has been addressed in commit fb59f1491058d58bdc3e8dd28f1773d1ac690a1f.

1 / 2
Source: MITRE
First published (updated )
Severity
8.2
Integer Overflow, Buffer Overflow
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:H

jq is a command-line JSON processor. An integer overflow vulnerability exists through version 1.8.1 within the jvpstringappend() and jvpstringcopyreplacebad functions, where concatenating strings with a combined length exceeding 2^31 bytes causes a 32-bit unsigned integer overflow in the buffer allocation size calculation, resulting in a drastically undersized heap buffer. Subsequent memory copy operations then write the full string data into this undersized buffer, causing a heap buffer overflow classified as CWE-190 (Integer Overflow) leading to CWE-122 (Heap-based Buffer Overflow). Any system evaluating untrusted jq queries is affected, as an attacker can crash the process or potentially achieve further exploitation through heap corruption by crafting queries that produce extremely large strings. The root cause is the absence of string size bounds checking, unlike arrays and objects which already have size limits. The issue has been addressed in commit e47e56d226519635768e6aab2f38f0ab037c09e5.

1 / 2
Source: MITRE
First published (updated )

7 vulnerabilities have been posted to https://github.com/jqlang/jq/security - 6 this week and one in March that I don't see in the list archives. Fixes appear to be available in their github repo, but not yet in a release.

https://github.com/jqlang/jq/security/advisories/GHSA-q3h9-m34w-h76f reports: Integer overflow in jvpstringappend and jvpstringcopyreplacebad allows heap buffer overflow

Affected versions: 1.8.1

Summary ------- An integer overflow in jvpstringappend() in src/jv.c causes a heap buffer overflow when concatenating strings whose combined length exceeds 2^31 bytes.

Details ------- The internal function jvpstringappend() computes the new buffer allocation size as:

// src/jv.c:1187 uint32t allocsz = (currlen + len) 2; if (allocsz < 32) allocsz = 32;

Both currlen and len are uint32t. When currlen + len >= 2^31, the multiplication by 2 overflows the 32-bit unsigned integer, wrapping allocsz to a small value (potentially 0, clamped to 32). The subsequent memcpy operations copy currlen + len bytes into the undersized buffer, causing a heap buffer overflow. The lengthhashed field ((currlen + len) << 1) suffers the same overflow, corrupting the stored string length.

Arrays and objects already have size limits, but strings have no equivalent bounds check. We have to limit the size of string so that the length does not overflow.

Similar vulnerability exists in jvpstringcopyreplacebad, too. [See GHSA for PoC] Impact ------ CWE-190 (Integer Overflow or Wraparound) leading to CWE-122 (Heap-based Buffer Overflow).

Any user or system that evaluates untrusted jq queries is affected. Attacker can easily crash the jq process by sending a crafted jq query. If the system uses a fixed jq query (that does not concatenate the input strings many times), attacker needs to send a huge JSON input to make it crash. Heap corruption may allow further exploitation depending on the allocator and environment. All versions of jq through 1.8.1 and current master version are affected.

Fix --- This issue was fixed by https://github.com/jqlang/jq/commit/e47e56d226519635768e6aab2f38f0ab037c09e5

Severity: High - 8.2 / 10 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:H CVE ID: CVE-2026-32316 https://github.com/jqlang/jq/security/advisories/GHSA-2hhh-px8h-355p says: Out-of-Bounds Read in jvparsesized() Error Formatting for Non-NUL-Terminated Counted Buffers

Summary ------- libjq exposes jvparsesized(const char string, int length) as a counted-buffer JSON parsing API, but its parse-error path later treats the same buffer as a NUL-terminated C string. If a caller passes malformed JSON in a non-NUL-terminated buffer, the error construction logic can read past the caller-supplied length, causing an out-of-bounds read.

Details ------- The vulnerable path is:

jvparsesized() -> jvparsesizedcustomflags() -> jvparsersetbuf(&parser, string, length, 0) -> parse failure -> jvstringfmt("%s (while parsing '%s')", ..., string)

Relevant code:

src/jv.h (line 245) src/jvparse.c (line 865) src/jvparse.c (line 896) src/jv.c (line 1528)

The parser correctly accepts a (pointer, length) pair, but when building the error message it formats string with %s, which causes vsnprintf() to continue reading memory until a \0 is found. This makes the error path ignore the explicit buffer length and turns a counted-buffer API into an unbounded read sink.

Reachability:

Real external source: any libjq consumer calling jvparsesized() with a counted buffer.

In-project internal uses such as fromjson and lexer paths also reach jvparsesized(), but those pass jq-managed strings that are already NUL-terminated, so the practical attack surface is the public API rather than the normal jq CLI path. [See GHSA for PoC] Impact ------

Only libjq is affected. A caller that uses jvparsesized() on untrusted malformed JSON in a non-NUL-terminated buffer can trigger an out-of-bounds read during error construction. Depending on memory layout and how the returned error string is logged or exposed, this can lead to memory disclosure or process termination.

Severity: Moderate CVE ID: CVE-2026-39979 Weaknesses: CWE-125 Out-of-bounds Read Credits: @HO-9 Reporter https://github.com/jqlang/jq/commit/2f09060afab23fe9390cce7cb860b10416e1bf5f states that it fixes CVE-2026-39979.

https://github.com/jqlang/jq/security/advisories/GHSA-32cx-cvvh-2wj9 advises: Embedded-NUL Truncation in jq CLI JSON Input Path Causes Prefix-Only Validation of Malformed Input

Summary ------- The normal jq CLI JSON input path uses fgets() and then derives the valid byte length with strlen() when parsing JSON input without a newline. If the input contains an embedded NUL byte, jq truncates the already-read buffer at the NUL and passes only the benign prefix to the JSON parser. As a result, jq may accept malformed input by validating only the prefix before the NUL.

Details ------- The reachable CLI path is:

CLI file/stdin input -> jqutilinputaddinput() / stdin default -> jqutilinputsetparser(..., jvparsernew(...)) -> jqutilinputnextinput() -> jqutilinputreadmore() -> strlen(state->buf) -> jvparsersetbuf(state->parser, state->buf, state->bufvalidlen, !islast)

Relevant code:

src/main.c (line 361) src/main.c (line 653) src/main.c (line 664) src/main.c (line 671) src/util.c (line 315) src/util.c (line 320) src/util.c (line 432)

The flaw is that the code does not use the actual number of bytes read by fgets(). Instead it uses strlen(state->buf), which stops at the first embedded NUL. Trailing bytes after the NUL may already have been consumed from the input stream, but they are silently excluded from parsing.

This is realistically reachable because it affects the stock jq CLI file and stdin parsing path used by end users. [See GHSA for PoC] Observed error:

jq: Bad JSON in --slurpfile ...: Invalid numeric literal at line 1, column 17

Impact

This issue can cause validation bypass in workflows that rely on jq to validate untrusted JSON before forwarding, storing, or otherwise acting on the original bytes. An attacker can place a benign JSON prefix before an embedded NUL and append malicious trailing data after it. jq may accept the prefix as valid JSON while silently ignoring the suffix, creating a parser differential between jq and downstream components that process the full input.

Severity: Low CVE ID: CVE-2026-33948 Weaknesses: No CWEs Credits: @HO-9 https://github.com/jqlang/jq/commit/6374ae0bcdfe33a18eb0ae6db28493b1f34a0a5b says it fixes CVE-2026-33948.

https://github.com/jqlang/jq/security/advisories/GHSA-xwrw-4f8h-rjvg states: Unbounded Recursion in jvsetpath() / jvgetpath() / delpathssorted()

Affected versions: <= 1.8.1

Summary ------- The jvsetpath(), jvgetpath(), and delpathssorted() functions in src/jvaux.c use unbounded recursion where the recursion depth equals the length of a caller-supplied path array. There is no depth limit check. When a path array with ~60,000 or more elements is supplied — either constructed by a jq filter expression or provided directly in attacker-controlled JSON input — the C call stack is exhausted, causing a segmentation fault (SIGSEGV) and immediate process crash.

This vulnerability bypasses the MAXPARSINGDEPTH (10,000) limit that protects the JSON parser, because path arrays can be constructed programmatically to arbitrary lengths without being constrained by parsing depth. Critically, the path array can be sourced entirely from attacker-controlled JSON input, making this exploitable in scenarios where a trusted jq filter processes untrusted data. [See GHSA for code analysis and PoC] Impact ------ - Denial of Service (Crash): Any jq process that calls setpath, getpath, or delpaths with a sufficiently long path array will crash with SIGSEGV. This is an unrecoverable crash — no error handling is possible. - Bypass of existing depth limits: The JSON parser's MAXPARSINGDEPTH (10,000) does not protect against this because path arrays are constructed at the jq runtime level, not during JSON parsing. An attacker can embed a flat array of 65,000 integers in a JSON document (only ~200 KB) that causes a crash when used as a path. - Affected real-world scenarios: - Web services using jq to transform or extract data from user-submitted JSON - CI/CD pipelines processing untrusted configuration or API responses with jq - Shell scripts that use setpath/getpath/delpaths on paths derived from input data - Any application embedding libjq where path arguments can be influenced by external input - Note: Unlike memory corruption vulnerabilities, stack overflow from recursion is generally not exploitable for code execution on modern systems with guard pages. The impact is limited to denial of service.

Severity: Moderate - 6.2 / 10 CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H CVE ID: CVE-2026-33947 Weaknesses: CWE-674 Uncontrolled Recursion Credits: @bg0d-glitch https://github.com/jqlang/jq/commit/fb59f1491058d58bdc3e8dd28f1773d1ac690a1f declares that it fixes CVE-2026-33947.

https://github.com/jqlang/jq/security/advisories/GHSA-6gc3-3g9p-xx28 announces: jq strindices missing runtime type checks lead to crash and limited memory disclosure

Affected versions: 1.8.1-dev commit 69785bf

Summary ------- strindices is the C builtin used by indices / index / rindex for string inputs. Its wrapper passes both arguments straight to jvstringindexes() without checking that they are strings, and jvstringindexes() itself only uses assert(). In release builds those checks disappear under -DNDEBUG. strindices(0) is enough to crash jq, and the same bug also gives an attacker controlled pointer dereference and a limited read/probe primitive.

Details ------- commit 69785bf77f86e2ea1b4a20ca86775916889e91c9, strindices is implemented in src/builtin.c like this

static jv fstringindexes(jqstate jq, jv a, jv b) { return jvstringindexes(a, b); }

jvstringindexes() in src/jv.c then blindly assumes both given args are strings:

jv jvstringindexes(jv j, jv k) { assert(JVPHASKIND(j, JVKINDSTRING)); assert(JVPHASKIND(k, JVKINDSTRING)); const char jstr = jvstringvalue(j); const char idxstr = jvstringvalue(k); }

In a debug build the assertions fire. In a normal release build they are compiled out, and jq dereferences j.u.ptr as if it were a valid jvpstring .

When the assertions are gone, jvstringvalue() treats j.u.ptr as a string header and jvstringlengthbytes() reads a length from that same fake object. This results in either 1. an easy crash with invalid input 2. a limited read primitive when a crafted number is used so its bit pattern is treated as a pointer. The number being crafted matters because default jq builds use decnum. A plain numeric literal doesn't give control of u.ptr, but arithmetic such as this does: (<bit-cast double> + 0) reaches jvnumber(double) and stores the IEEE-754 bits of that double in the same union field which is later read as u.ptr

PoC --- Crash: jq -n 'strindices(0)'

Controlled pointer dereference:

import struct, subprocess

def asdouble(u64): return struct.unpack("<d", struct.pack("<Q", u64))[0]

# because we want jstr = addr, the fake jvpstring sits 16 bytes earlier addr = 0x4141414141414151 expr = f"({asdouble(addr - 16)!r} + 0) | strindices(\"\\u0000\")" result = subprocess.run(["jq", "-n", expr]) print(result.returncode) # sigsegv in python

Impact ------

Anything that runs untrusted jq filters against a release build can be crashed very easily. If the system uses a fixed jq query (such that does not use the internal strindices filter), it is not affected. The same bug also gives limited read behavior because values which are not strings can be treated as fake string objects and walked by strindices. In a real deployment that means an attacker can use the exit status as a mapped/unmapped probe, and in favorable cases can get some bytes back through the strindices position output.

Severity: Moderate - 6.1 / 10 CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:H CVE ID: CVE-2026-39956 Weaknesses: CWE-125 Out-of-bounds Read CWE-476 NULL Pointer Dereference CWE-843 Access of Resource Using Incompatible Type ('Type Confusion') Credits: @tlsbollei Reporter https://github.com/jqlang/jq/commit/fdf8ef0f0810e3d365cdd5160de43db46f57ed03 claims to fix CVE-2026-39956.

https://github.com/jqlang/jq/security/advisories/GHSA-wwj8-gxm6-jc29 expresses: Algorithmic complexity DoS via hardcoded MurmurHash3 seed

Summary ------- jq uses MurmurHash3 with a compile-time constant seed 0x432A9843 (src/jv.c:1200) for all JSON object hash table operations. Since the seed is hardcoded and publicly visible in source, an attacker can precompute hash collisions offline and construct a JSON object where all keys hash to the same bucket. This degrades operations from O(1) to O(n), making any jq expression O(n^2). Only ~100KB of crafted JSON needed — far more practical than the heap overflow issues.

Details ------- File: src/jv.c, line 1200

static const uint32t HASHSEED = 0x432A9843;

Used at line 1219:

static uint32t jvpvalhash(jv val) { uint32t h1 = HASHSEED; // ... MurmurHash3 body ... }

Many languages randomize hash seeds at startup to prevent this (Python 3.3+, Ruby 1.9+, Perl 5.18+). jq does not. [See GHSA for PoC] Severity: High - 7.5 / 10 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H CVE ID: CVE-2026-40164 Weaknesses: CWE-328 Use of Weak Hash CWE-407 Inefficient Algorithmic Complexity Credits: @AsafMeizner Reporter https://github.com/jqlang/jq/commit/0c7d133c3c7e37c00b6d46b658a02244fdd3c784 appears to mitigate this, but does not list the CVE id.

https://github.com/jqlang/jq/security/advisories/GHSA-gf4g-95wj-4q4r discloses: jq args2obj() Heap-Use-After-Free Vulnerability Report

Affected versions: 1.8.1 (commit ref:b33a763)

Summary ------- A potential heap-use-after-free vulnerability exists in jq's args2obj() function at src/execute.c:1218. The bug is in the public jqcompileargs() API's array argument processing path: when called with an array of 2+ named argument entries, freed heap memory is read (CWE-416); with 1+ entries, a double-free occurs (CWE-415). The standard jq CLI binary is not affected, as it always passes an object (not an array) to args2obj(). It appears the bug was introduced in commit b279713e (2017-02-26) and affects jq HEAD (jq-1.8.1-32-gb33a763).

Details ------- Root cause: The strings kk ("name") and vk ("value") are allocated once before the loop but passed directly to jvobjectget(), which consumes (frees) both its arguments. On the first iteration, kk and vk are freed. On subsequent iterations, they are dangling pointers — jvpstringhash() reads from freed heap memory. After the loop, jvfree(kk) / jvfree(vk) trigger a double-free.

// src/execute.c:1208-1223 jv kk = jvstring("name"); jv vk = jvstring("value"); jvarrayforeach(args, i, v) r = jvobjectset(r, jvobjectget(jvcopy(v), kk), jvobjectget(v, vk)); jvfree(kk); // double-free: already freed by jvobjectget() jvfree(vk);

Git history: Commit b279713e refactored inline array processing in jqcompileargs() into the args2obj() helper. The original code created fresh jvstring("name") / jvstring("value") on each iteration; the refactored version hoisted them into locals but failed to account for jvobjectget() consuming its key argument.

[See GHSA for PoC]

Impact

CWE-416 (Use After Free) / CWE-415 (Double Free). The vulnerability is reachable through the public jqcompileargs() API when called with array arguments — not through the CLI binary. Heap corruption from the UAF and double-free may lead to arbitrary code execution via corrupted heap metadata, though no exploit has been demonstrated. All downstream consumers of jqcompileargs() that pass array arguments have been affected since commit b279713e (2017-02-26).

My name is Scott Seal, and I work at Trail of Bits. Per the instructions of my employer, I am required to provide the following disclosure:

This bug was found as part of follow-on research from DARPA's AI Cyber Challenge (AIXCC), where Trail of Bits built Buttercup, a Cyber Reasoning System that combines static analysis, fuzzing, and large language models to find and fix vulnerabilities.

https://www.darpa.mil/research/programs/ai-cyber https://www.trailofbits.com/buttercup/

Severity: Low CVE ID: No known CVE Weaknesses CWE-415 Double Free CWE-416 Use After Free Credits: @sseal Reporter https://github.com/jqlang/jq/commit/3985b80ce50bd75c6eb5a97cb3348c3f835ca8e0 includes "Fixes GHSA-gf4g-95wj-4q4r."

-- -Alan Coopersmith- alan.coopersmith () oracle com Oracle Solaris Engineering - https://blogs.oracle.com/solaris

Severity
6.2
Buffer Overflow
AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

jq is a command-line JSON processor. Version 1.7 is vulnerable to heap-based buffer overflow. Version 1.7.1 contains a patch for this issue.

First published (updated )
Severity
7.5
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

decToString in decNumber/decNumber.c in jq 88f01a7 has a one-byte out-of-bounds write via the " []-1.2e-1111111111" input. NOTE: this is not the same as CVE-2023-50246. The CVE-2023-50246 71c2ab5 reference mentions -10E-1000010001, which is not in normalized scientific notation.

First published (updated )
Severity
6.2
Buffer Overflow
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H

jq is a command-line JSON processor. Version 1.7 is vulnerable to stack-based buffer overflow in builds using decNumber. Version 1.7.1 contains a patch for this issue.

First published (updated )

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203