Nimiq is a Rust implementation of the Nimiq Proof-of-Stake protocol based on the Albatross consensus algorithm. Prior to 1.6.0, a malicious state-sync peer can crash a syncing node by sending a crafted TrieChunk proof containing two TrieProofNode values with identical keys. TrieProof::verify calls TrieProofNode::child_index in primitives/src/trie/trie_proof_node.rs, where is_prefix_of accepts equal keys and KeyNibbles::get is called at the key length, returns None, and is unconditionally unwrapped. Untrusted ResponseChunk data reaches commit_chunks, put_chunk, and proof.verify before cryptographic proof validation, so the attacker does not need a valid proof. Exploitation requires the attacker to be selected as the victim's sync peer during state sync, and the resulting panic is transient because the node restarts and resynchronizes. This issue is fixed in version 1.6.0.
Nimiq is a Rust implementation of the Nimiq Proof-of-Stake protocol based on the Albatross consensus algorithm. Prior to 1.6.0, a malicious state-sync peer can crash a syncing node by sending a crafted TrieChunk whose proof contains a TrieNodeChild suffix that is individually valid but exceeds the 63-byte KeyNibbles backing array when combined with the parent key. KeyNibbles::Add in primitives/src/key_nibbles.rs performs the combined slice operation without checking the total length, and the input reaches put_chunk, TrieNodeChild::key, and TrieNodeChild::is_stump before proof.verify, so the attacker does not need a valid cryptographic proof. Exploitation requires the attacker to be selected as the victim's sync peer during state sync. The resulting out-of-bounds panic is transient because the node restarts and resynchronizes. This issue is fixed in version 1.6.0.
Nimiq is a Rust implementation of the Nimiq Proof-of-Stake protocol based on the Albatross consensus algorithm. Prior to version 1.5.0, a remote, unauthenticated denial-of-service vulnerability in MerkleRadixTrie::put_chunk allows any state-sync peer to crash any node performing state synchronization (freshly joining nodes and recovering nodes). This issue has been patched in version 1.5.0.
Nimiq is a Rust implementation of the Nimiq Proof-of-Stake protocol based on the Albatross consensus algorithm. Prior to version 1.5.0, a remote peer can crash any full node by sending a RequestBatchSet message containing the genesis block's hash. The handler calls get_epoch_chunks which iterates backwards through macro blocks using Policy::macro_block_before. When it reaches the genesis block number, macro_block_before panics with "No macro blocks before genesis block". This issue has been patched in version 1.5.0.
A denial-of-service vulnerability exists in nimiq core-rs-albatross prior to version 1.4.0. The Ed25519PublicKey::delinearize() function calls unwrap() on curve point decompression, which panics if given invalid public key bytes that do not represent a valid point on the Ed25519 curve. This can crash the hosting process. The issue is fixed in version 1.4.0.
Nimiq is a Rust implementation of the Nimiq Proof-of-Stake protocol based on the Albatross consensus algorithm. Prior to version 1.4.0, iIn handle_dht_get(), the DhtResults accumulator is only initialized when the first DHT record passes verification. If the first record fails (from a malicious DHT node), DhtResults is never created, and all subsequent valid records are discarded with "DHT inconsistent state" errors. This issue has been patched in version 1.4.0.
Nimiq core-rs-albatross versions prior to 1.4.0 contain a vulnerability where the LightBlockchain::rebranch() function improperly updates blockchain state when adopting a fork chain ending in a macro block. This leads to stale macro block and validator state, causing verification failures and stalling the light client's chain progression. The issue is fixed in version 1.4.0.
Nimiq is a Rust implementation of the Nimiq Proof-of-Stake protocol based on the Albatross consensus algorithm. Prior to version 1.4.0, a logic flaw in BlockInclusionProof::is_block_proven causes the function to return true without performing any cryptographic verification when get_interlink_hops yields an empty hop list. This occurs when the target block is at the election block position immediately preceding the election head's epoch. An attacker providing transaction inclusion proofs can forge a MacroBlock header for that epoch position and have it accepted as "proven" without any hash or signature verification. This issue has been patched in version 1.4.0.
Nimiq is a Rust implementation of the Nimiq Proof-of-Stake protocol based on the Albatross consensus algorithm. network-libp2p handles kad get-record query progress in handle_dht_get (network-libp2p/src/swarm.rs). Prior to version 1.4.0, when a peer returns a FoundRecord, the code verifies the record via dht_verifier.verify(&record.record). On verifier error, handle_dht_get logs and returns early without completing the oneshot used by Network::dht_get, and without cleaning up per-query bookkeeping. Later query progress can hit the "DHT inconsistent state" path and also return without cleanup. Because Network::dht_get awaits the oneshot without a timeout, the caller future can hang indefinitely. This issue has been patched in version 1.4.0.
nimiq-blockchain provides persistent block storage for Nimiq's Rust implementation. In versions 1.3.0 and prior, network-libp2p discovery accepts signed PeerContact updates from untrusted peers and stores them in a peer contact book, eventually leading to address book crash. A PeerContact can legally contain an empty addresses list (no intrinsic validation enforces non-empty). Later, PeerContactBook::known_peers builds an address book by taking addresses.first().expect("every peer should have at least one address"). If the attacker has inserted a signed peer contact with addresses=[], any call to get_address_book (RPC/web client) can panic and crash the node/RPC task depending on panic settings. This issue has been fixed in version 1.4.0.
nimiq-blockchain provides persistent block storage for Nimiq's Rust implementation. In versions 1.3.0 and below, a malicious network peer can crash any Nimiq full node by publishing a crafted Kademlia DHT record. The maliciously crafted record would contain a TaggedSigned<ValidatorRecord, KeyPair> with a signature field whose byte length is not exactly 64 in order to cause a crash. When the victim node's DHT verifier calls TaggedSigned::verify, execution reaches Ed25519Signature::from_bytes(sig).unwrap() in the TaggedPublicKey implementation for Ed25519PublicKey. The from_bytes call fails because ed25519_zebra::Signature::try_from rejects slices not 64 bytes, and the unwrap() panics. The BLS TaggedPublicKey implementation correctly returns false on error; only the Ed25519 implementation panics. This issue has been fixed in version 1.4.0.
A vulnerability in nimiq-blockchain versions prior to 1.3.0 allows a remote peer to cause a panic via improper input validation in the HistoryStore component. Specifically, the function put_historic_txns uses an assert to enforce block number invariants, which can be violated by a malformed history list during history synchronization, leading to a denial of service. The issue is fixed in version 1.3.0. No known workarounds exist.
A reachable assertion vulnerability exists in nimiq/core-rs-albatross versions 1.2.2 and below. An unauthenticated peer can send a crafted RequestMacroChain message that causes the handler to panic due to an unexpected micro block hash being treated as a macro block hash. This leads to a denial of service condition by crashing the task handling the message. The issue is fixed in version 1.3.0.
nimiq/core-rs-albatross is a Rust implementation of the Nimiq Proof-of-Stake protocol based on the Albatross consensus algorithm. Prior to version 1.3.0, an untrusted peer could crash a validator by publishing a signed tendermint proposal message where signer == validators.num_validators(). ProposalSender::send uses > instead of >= for the signer bounds check, so the equality case passes and reaches validators.get_validator_by_slot_band(signer), which panics with an out-of-bounds index before any signature verification runs. This issue has been fixed in version 1.3.0.
nimiq-blockchain provides persistent block storage for Nimiq's Rust implementation. In 1.3.0 and earlier, block timestamp validation enforces that timestamp >= parent.timestamp for non-skip blocks and timestamp == parent.timestamp + MIN_PRODUCER_TIMEOUT for skip blocks, but there is no visible upper bound check against the wall clock. A malicious block-producing validator can set block timestamps arbitrarily far in the future. This directly affects reward calculations via Policy::supply_at() and batch_delay() in blockchain/src/reward.rs, inflating the monetary supply beyond the intended emission schedule.
nimiq/core-rs-albatross is a Rust implementation of the Nimiq Proof-of-Stake protocol based on the Albatross consensus algorithm. Prior to version 1.3.0, two peer-facing consensus request handlers assume that the history index is always available and call blockchain.history_store.history_index().unwrap() directly. That assumption is false by construction. HistoryStoreProxy::history_index() explicitly returns None for the valid HistoryStoreProxy::WithoutIndex state.when a full node is syncing or otherwise running without the history index, a remote peer can send RequestTransactionsProof or RequestTransactionReceiptsByAddress and trigger an Option::unwrap() panic on the request path. This issue has been patched in version 1.3.0.
nimiq/core-rs-albatross is a Rust implementation of the Nimiq Proof-of-Stake protocol based on the Albatross consensus algorithm. Prior to version 1.3.0, the discovery handler accepts a peer-controlled limit during handshake and stores it unchanged. The immediate HandshakeAck path then honors limit = 0 and returns zero contacts, which makes the session look benign. Later, after the same session reaches Established, the periodic update path computes self.peer_list_limit.unwrap() as usize - 1. With limit = 0, that wraps to usize::MAX and then in rand 0.9.2, choose_multiple() immediately attempts Vec::with_capacity(amount), which deterministically panics with capacity overflow. This issue has been patched in version 1.3.0.
nimiq/core-rs-albatross is a Rust implementation of the Nimiq Proof-of-Stake protocol based on the Albatross consensus algorithm. Prior to version 1.3.0, an elected validator proposer can send an election macro block whose header.interlink does not match the canonical next interlink. Honest validators accept that proposal in verify_macro_block_proposal() because the proposal path validates header shape, successor relation, proposer, body root, and state, but never checks the interlink binding for election blocks. The same finalized block is later rejected by verify_block() during push with InvalidInterlink. Because validators prevote and precommit the malformed header hash itself, the failure happens after Tendermint decides the block, not before voting. This issue has been patched in version 1.3.0.
nimiq/core-rs-albatross is a Rust implementation of the Nimiq Proof-of-Stake protocol based on the Albatross consensus algorithm. Prior to version 1.2.2, a malicious or compromised validator that is elected as proposer can publish a macro block proposal where `header.body_root` does not match the actual macro body hash. The proposal can pass proposal verification because the macro proposal verification path validates the header but does not validate the binding `body_root == hash(body)`; later code expects this binding and may panic on mismatch, crashing validators. Note that the impact is only for validator nodes. The patch for this vulnerability is formally released as part of v1.2.2. The patch adds the corresponding body root verification in the proposal checks. No known workarounds are available.