Skip to main content

nimiq-primitives CVE-2026-54541

| EUVDEUVD-2026-77576 LOW
Uncaught Exception (CWE-248)
2026-07-16 https://github.com/nimiq/core-rs-albatross GHSA-46wq-28cx-mhw4
3.7
CVSS 3.1 · Vendor: https://github.com/nimiq/core-rs-albatross

Severity by source

Vendor (https://github.com/nimiq/core-rs-albatross) PRIMARY
3.7 LOW
AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L
vuln.today AI
3.7 LOW

AC:H for probabilistic peer-selection requirement during active sync; A:L for transient self-healing crash only; C and I are N with no data exposure or state corruption.

3.1 AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L
4.0 AV:N/AC:H/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N

Primary rating from Vendor (https://github.com/nimiq/core-rs-albatross).

CVSS VectorVendor: https://github.com/nimiq/core-rs-albatross

Attack Vector
Network
Attack Complexity
High
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
Low

Lifecycle Timeline

2
Source Code Evidence Fetched
Jul 16, 2026 - 20:36 vuln.today
Analysis Generated
Jul 16, 2026 - 20:36 vuln.today

DescriptionCVE.org

Impact

A malicious peer acting as a state-sync source can crash a syncing node by sending a crafted TrieChunk whose proof contains two TrieProofNodes with identical keys. TrieProof::verify() calls TrieProofNode::child_index() (primitives/src/trie/trie_proof_node.rs:94), which unconditionally unwraps KeyNibbles::get(self.key.len()). Because is_prefix_of returns true for two equal keys, execution reaches get(len), which returns None, and the unwrap() panics.

The panic is reached from untrusted network input (ResponseChunkcommit_chunksput_chunkproof.verify()) before any cryptographic proof verification, so the attacker does not need to produce a valid proof. Exploitation requires the attacker to be selected as the victim's sync peer while the victim is performing state sync, and the resulting crash is transient (the node restarts and re-syncs).

Affected: core-rs-albatross <= 1.5.1 (nimiq-primitives).

Patches

Fixed in 1.6.0 via https://github.com/nimiq/core-rs-albatross/pull/3789 (commit 41d35ace). child_index now rejects equal-length keys and returns MerkleRadixTrieError::WrongPrefix instead of unwrapping.

Workarounds

None other than syncing only from trusted peers. Upgrade to 1.6.0.

AnalysisAI

Panic-induced denial of service in nimiq-primitives (core-rs-albatross <= 1.5.1) allows a malicious state-sync peer to crash a syncing Nimiq blockchain node by sending a crafted TrieChunk whose proof contains two TrieProofNode entries with identical keys. The panic fires in TrieProof::verify() before any cryptographic proof validation occurs, so no valid proof is required to trigger it. The crash is transient - the node restarts and re-syncs - and no public exploit has been identified at time of analysis.

Technical ContextAI

The affected package is pkg:rust/nimiq-primitives, part of the core-rs-albatross Nimiq proof-of-stake blockchain node written in Rust. During state synchronization, the node accepts ResponseChunk messages from a designated sync peer and processes them via commit_chunks → put_chunk → TrieProof::verify(). Inside verify(), the method TrieProofNode::child_index() at primitives/src/trie/trie_proof_node.rs:94 calls KeyNibbles::get(self.key.len()).unwrap(). The guard is_prefix_of returns true when two keys are identical (a key is trivially a prefix of itself), so when two proof nodes share the same key, execution reaches the get(len) call with an out-of-bounds index, returning None, and the unconditional .unwrap() panics. This is classified under CWE-248 (Unchecked Return Value). The patch in 1.6.0 (PR #3789, commit 41d35ace) adds a strict-prefix length check (self.key.len() == child_prefix.len() is now rejected) and replaces the .unwrap() with .ok_or(MerkleRadixTrieError::WrongPrefix), eliminating both the logical error and the panic path.

RemediationAI

Upgrade core-rs-albatross to version 1.6.0, which is the vendor-released patched version confirmed via the release tag at https://github.com/nimiq/core-rs-albatross/releases/tag/v1.6.0. The fix is delivered through PR #3789 (commit 41d35ace) and eliminates the panic by enforcing strict-prefix semantics in child_index() and replacing the unsafe .unwrap() with a proper error return. The only available workaround prior to patching is to configure the node to accept state-sync connections exclusively from a known-trusted peer set, which prevents a malicious peer from acting as a sync source; this may not be feasible in fully permissionless deployments and should be treated as a temporary measure only. No other compensating controls are documented by the vendor.

Share

CVE-2026-54541 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy