Apr 14, 2026·6 min read·4 visits
Unauthenticated remote attackers can crash Nimiq Albatross nodes (versions <= 1.2.2) via a crafted P2P message that exploits a missing block type check, triggering a reachable assertion (CWE-617) and an application panic.
The Nimiq Albatross consensus implementation suffers from a remote Denial of Service (DoS) vulnerability. An unauthenticated peer can trigger a reachable assertion by sending a crafted RequestMacroChain message containing a micro block hash, leading to a Rust panic and subsequent crash of the consensus task.
The Nimiq Albatross protocol implements a Proof-of-Stake consensus mechanism. The nimiq-consensus crate handles peer-to-peer communications, including the synchronization of blockchain state across the network. Nodes rely on specific synchronization messages to determine the correct chain state and identify missing blocks.
One of these synchronization messages is RequestMacroChain. This message assists a receiver in finding a common ancestor on the macro chain by providing a list of block hashes, known as locators. The receiving node evaluates these locators against its local chain state to establish a synchronization starting point.
A vulnerability exists in how the consensus task processes the locators provided in the RequestMacroChain message. Due to insufficient validation of the locator block type, an unauthenticated attacker can force the node into an invalid state. This flaw is classified as CWE-617 (Reachable Assertion), leading directly to a localized Denial of Service.
The root cause of CVE-2026-34069 resides in the RequestMacroChain message handler within consensus/src/messages/handlers.rs. The handler iterates through the provided locators to identify the first block that exists on the local main chain. In vulnerable versions, the application strictly verified the chain_info.on_main_chain boolean property.
The logic failed to verify whether the identified block was a macro block. The Nimiq blockchain contains both macro blocks and micro blocks, both of which can legitimately reside on the main chain. After identifying a valid main chain block, the handler proceeded under the assumption that the block was inherently a macro block.
The handler subsequently invoked blockchain.get_macro_blocks() using the selected block hash. If the provided hash belonged to a micro block, the function correctly generated a BlockchainError::BlockIsNotMacro result. The application utilized the .unwrap() method on this result, assuming successful execution.
Invoking .unwrap() on an Err variant in Rust triggers an immediate panic. Because this code executed within the context of the main consensus task, the panic caused the entire task to crash. This abruptly terminated the node's ability to participate in the network consensus process.
The vulnerable implementation explicitly trusted the locator block type based solely on its inclusion in the main chain. The code iterated over the locators, assigned the first matching hash to start_block_hash, and immediately broke the loop.
// Vulnerable logic in consensus/src/messages/handlers.rs
for locator in locators {
if let Ok(chain_info) = blockchain.get_chain_info(locator, false) {
if chain_info.on_main_chain {
start_block_hash = Some(locator.clone());
break;
}
}
}
// ... execution continues ...
let election_blocks = blockchain.get_macro_blocks(&start_block_hash, ...).unwrap(); // Panic occurs hereThe patch introduced in commit ae6c1e92342e72f80fd12accbe66ee80dd6802ac modifies the conditional check to validate the block type explicitly. It retrieves the full block data and invokes the is_macro() method before accepting the locator.
// Patched logic in consensus/src/messages/handlers.rs
for locator in locators {
if let Ok(chain_info) = blockchain.get_chain_info(locator, false) {
if chain_info.on_main_chain {
// Validate that the locator is a macro block before using it.
if let Ok(block) = blockchain.get_block(locator, false) {
if block.is_macro() {
start_block_hash = Some(locator.clone());
break;
}
}
// Skip micro blocks and continue searching for a macro block.
}
}
}By adding the explicit block.is_macro() check, the patched code guarantees that only valid macro blocks are passed to blockchain.get_macro_blocks(). If an attacker supplies a micro block hash, the loop safely ignores it and evaluates the next locator in the list.
Exploitation requires no authentication and relies entirely on standard P2P network interactions. The attacker begins by identifying a target Nimiq Albatross node running version 1.2.2 or earlier. The target node must be actively listening for P2P connections, typically on TCP port 8444 or 8445.
The attacker queries the public blockchain state to identify the hash of a recent micro block that resides on the main chain. They construct a custom RequestMacroChain message, populating the locators array with this specific micro block hash. This message is then transmitted directly to the target node over the established P2P connection.
Upon receiving the payload, the target node's message handler processes the locators array. It successfully resolves the micro block hash and confirms its presence on the main chain. The handler then passes the hash to get_macro_blocks(), receives an error, and panics during the .unwrap() call.
The resulting panic terminates the consensus task. Depending on the process management configuration of the deployment environment, the node may restart automatically, or it may remain offline. Repeated exploitation allows an attacker to maintain a persistent denial of service state.
The primary impact of CVE-2026-34069 is a Denial of Service affecting the core consensus functionality of a Nimiq node. A successful attack isolates the node from the network, preventing it from validating transactions, participating in elections, or synchronizing future blocks. The vulnerability carries a CVSS v3.1 base score of 5.3, reflecting the low complexity and lack of required privileges.
The CVSS vector evaluates to CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L. While the availability impact is classified as low under standard CVSS metrics, the operational consequence for a consensus-driven blockchain network is notable. Removing nodes from the network reduces overall decentralization and disrupts the operations of affected node operators.
The vulnerability does not compromise data confidentiality or integrity. The attacker cannot extract private keys, manipulate account balances, or execute arbitrary code. The memory safety guarantees of Rust confine the panic to thread termination, preventing memory corruption or exploitable state variations.
The EPSS score for this vulnerability has not yet matured, given its recent disclosure. However, the simplicity of the attack vector and the availability of proof-of-concept tests in the public repository increase the likelihood of widespread probing. Automated scanners can trivially replicate the required P2P messaging sequence.
The official remediation for CVE-2026-34069 requires updating the Nimiq Albatross client to version 1.3.0 or later. The patch eliminates the reachable assertion by implementing robust type checking prior to data processing. Node operators must restart their services after applying the update to ensure the patched consensus logic executes.
There are no viable configuration-level workarounds for this vulnerability. The flawed logic resides within the core P2P messaging handler, which cannot be disabled without completely severing the node's ability to synchronize with the network. Network-level mitigation via firewalls is impractical, as filtering P2P traffic generally disrupts standard blockchain operations.
Security teams managing Rust applications should review this vulnerability as a case study in unsafe error handling. Developers must audit codebases for instances where .unwrap(), .expect(), or unreachable!() are called on results derived from untrusted network input. Proper error propagation utilizing the ? operator or explicit match blocks prevents application crashes and improves overall resilience.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L| Product | Affected Versions | Fixed Version |
|---|---|---|
nimiq/core-rs-albatross Nimiq | <= 1.2.2 | 1.3.0 |
| Attribute | Detail |
|---|---|
| CVE ID | CVE-2026-34069 |
| CVSS v3.1 Score | 5.3 |
| CWE ID | CWE-617 (Reachable Assertion) |
| Attack Vector | Network |
| Privileges Required | None |
| Exploit Status | Proof of Concept |
| CISA KEV | Not Listed |
The application contains an assert() or similar statement that can be triggered by an attacker, which leads to an application exit or other behavior that is more severe than necessary.