Automated Threat Modeling

jq CVE-2026-40164: Brief Summary of Hardcoded Hash Seed Enabling Algorithmic Complexity DoS

A brief summary of CVE-2026-40164, a high-severity algorithmic complexity vulnerability in jq. A hardcoded MurmurHash3 seed lets attackers craft small JSON payloads whose keys collide in the hash table, causing severe CPU exhaustion.

CVE Analysis

7 min read

ZeroPath CVE Analysis
ZeroPath CVE Analysis

2026-04-13

jq CVE-2026-40164: Brief Summary of Hardcoded Hash Seed Enabling Algorithmic Complexity DoS
Experimental AI-Generated Content

This CVE analysis is an experimental publication that is completely AI-generated. The content may contain errors or inaccuracies and is subject to change as more information becomes available. We are continuously refining our process.

If you have feedback, questions, or notice any errors, please reach out to us.

[email protected]

Introduction

A roughly 100 KB JSON file can pin a jq process at 100% CPU for minutes, and a 2 MB file can stall it for hours. The cause, tracked as CVE-2026-40164, is a hardcoded MurmurHash3 seed that ships in every version of jq. Anyone can use that seed to precompute hash collisions offline, which turns ordinary JSON processing into a quadratic-time operation.

jq is a lightweight, zero-dependency command-line JSON processor written in portable C, often described as "sed for JSON." Stephen Dolan created it in 2012, and it has since become a standard utility in software engineering, embedded in CI/CD pipelines, web service backends, and data processing scripts on Linux, macOS, and Windows. Because jq is everywhere, the attack surface for this vulnerability is broad and often invisible.

Technical Information

Root Cause: Deterministic Hashing with a Public Seed

The problem sits at line 1200 of src/jv.c, where jq defines a compile-time constant seed for its MurmurHash3 implementation:

static const uint32_t HASH_SEED = 0x432A9843;

jq uses this seed for every JSON object hash table operation. Because the seed is hardcoded and visible in the public source code, an adversary can replicate the exact hash function locally and brute-force sets of keys that all land in the same hash bucket. Many modern language runtimes (Python 3.3+, Perl, Ruby, PHP) randomize their hash seeds at process startup specifically to prevent this class of attack. jq did not.

Collision Impact: O(1) to O(n²)

When jq loads a JSON object, it inserts the object's keys into a hash table. Under normal conditions, lookups are O(1). When all keys collide into a single bucket, each lookup becomes O(n), because the implementation has to walk a linear chain. Any jq expression that touches the object's keys (which is nearly all of them) then performs O(n) lookups across O(n) keys, for O(n²) total work.

The advisory's benchmarks show the quadratic scaling:

Collision Key CountApproximate Payload SizeProcessing Time
1,000 keys20 KB1 second
10,000 keys200 KB100 seconds
100,000 keys2 MB3 hours

This is a textbook algorithmic complexity attack (CWE-407), made worse by a reversible hash with a known seed (CWE-328). A 200 KB payload, trivial to send over any network, costs the target 100 seconds of CPU time.

Attack Flow

  1. Offline key generation. The attacker implements MurmurHash3 with the known seed 0x432A9843 in any language, then enumerates candidate strings and keeps only those whose hash matches a chosen target value.

  2. Payload construction. The attacker assembles a JSON object from the colliding keys. 10,000 colliding keys (~200 KB) are enough to stall each jq invocation for roughly 100 seconds, which is a meaningful denial of service.

  3. Delivery. The attacker sends the crafted JSON to any endpoint or pipeline that processes it with jq. Common vectors include:

    • API responses consumed by curl | jq patterns in CI/CD pipelines
    • JSON payloads submitted to web services that use jq for server-side processing
    • Data feeds ingested by ETL scripts
  4. Impact. The jq process enters a tight CPU loop. Nothing crashes. The process just stops responding until the quadratic computation finishes. In a pipeline, that can block deployments, stall monitoring, or exhaust worker pools.

Comparison to Previous jq Vulnerabilities

The advisory notes that this attack is far more practical than existing heap overflow issues in jq, which required payloads of about 1.43 GB. CVE-2026-40164 causes comparable or greater disruption with a payload four orders of magnitude smaller.

The Fix

Commit 0c7d133c3c7e37c00b6d46b658a02244fdd3c784 replaces the static seed with a random seed initialized at runtime from system entropy. The suggested patch to src/jv.c is:

- static const uint32_t HASH_SEED = 0x432A9843; + static uint32_t hash_seed; + __attribute__((constructor)) + static void init_hash_seed(void) { + #if defined(HAVE_ARC4RANDOM) + hash_seed = arc4random(); + #elif defined(HAVE_GETENTROPY) + if (getentropy(&hash_seed, sizeof(hash_seed)) != 0) + hash_seed = (uint32_t)getpid() ^ (uint32_t)time(NULL); + #else + int fd = open("/dev/urandom", O_RDONLY); + if (fd >= 0) { read(fd, &hash_seed, 4); close(fd); } + else hash_seed = (uint32_t)getpid() ^ (uint32_t)time(NULL); + #endif + }

With this change, each jq process gets a unique seed, which makes offline collision precomputation infeasible.

Affected Systems and Versions

All versions of jq are affected. The advisory lists no version range boundary. The hardcoded seed has been in src/jv.c since the hash table was first implemented. At the time of the advisory, there is no officially patched release. The fix is available only as commit 0c7d133c3c7e37c00b6d46b658a02244fdd3c784 in the jqlang/jq repository.

Any deployment that passes untrusted or externally sourced JSON through jq is vulnerable. This includes but is not limited to:

  • CI/CD pipelines using curl | jq to consume external API responses
  • Web services that invoke jq for server-side JSON transformation
  • Data processing and ETL scripts that ingest feeds from third-party sources

Vendor Security History

The jqlang organization maintains jq on GitHub and has a history of fixing security issues promptly. The jq 1.8.1 release on July 1, 2025, included fixes for multiple security vulnerabilities:

  • CVE-2025-49014: Heap use after free
  • CVE-2024-23337: Signed integer overflow

Given that record, an official release with the hash seed randomization will likely follow. Organizations should watch the jq releases page for updates.

References

Detect & fix
what others miss

Works with
  • GitHub
  • GitLab
  • Bitbucket
  • Azure DevOps Services
  • Gerrit
  • CVS
  • Jira
  • Linear
  • Slack
  • Security Compass
Explore integrations
Security magnifying glass visualization