CVE-2026-40092 Overview
CVE-2026-40092 is a denial-of-service vulnerability in nimiq-blockchain, the persistent block storage component of Nimiq's Rust implementation (core-rs-albatross). Versions 1.3.0 and below crash when a malicious network peer publishes a crafted Kademlia Distributed Hash Table (DHT) record. The crash originates in the Ed25519 TaggedPublicKey::verify implementation, which calls unwrap() on a Signature::from_bytes result without handling the error case. Any signature byte slice not exactly 64 bytes long triggers a panic, terminating the full node process. The issue is fixed in version 1.4.0.
Critical Impact
A single unauthenticated peer can remotely crash any Nimiq full node by broadcasting one malformed DHT record, enabling network-wide denial of service against the Nimiq blockchain.
Affected Products
- Nimiq core-rs-albatross (nimiq-blockchain crate) versions 1.3.0 and earlier
- Nimiq Rust full node implementations using the affected tagged_signing module
- Nodes participating in Kademlia DHT discovery and validator record exchange
Discovery Timeline
- 2026-05-20 - CVE-2026-40092 published to NVD
- 2026-05-20 - Last updated in NVD database
Technical Details for CVE-2026-40092
Vulnerability Analysis
The vulnerability is an unchecked return value [CWE-252] that produces a reachable panic in safe Rust. When a Nimiq full node receives a Kademlia DHT record containing a TaggedSigned<ValidatorRecord, KeyPair>, the DHT verifier invokes TaggedSigned::verify. For Ed25519 keys, this dispatches to the TaggedPublicKey implementation on Ed25519PublicKey, which deserializes the signature bytes via Ed25519Signature::from_bytes(sig).unwrap().
The underlying ed25519_zebra::Signature::try_from enforces a strict 64-byte length requirement. Any other length causes from_bytes to return Err, and the subsequent unwrap() panics. The BLS variant of TaggedPublicKey handles the same error path correctly by returning false, isolating the defect to the Ed25519 implementation. Because DHT records propagate peer-to-peer, a single crafted record can cascade across the network and take down multiple validators.
Root Cause
The root cause is the use of unwrap() on a fallible deserialization call inside a verification routine that is reachable from untrusted network input. The verify contract is expected to return a boolean, but the Ed25519 path conflates malformed input with a programmer error and aborts the process.
Attack Vector
An attacker joins the Nimiq peer-to-peer network as an ordinary Kademlia participant. They construct a TaggedSigned record where the signature field is any length other than 64 bytes, sign-wrap it appropriately, and publish it to the DHT. Each victim node that retrieves and verifies the record panics during signature parsing. No authentication, prior trust relationship, or user interaction is required.
// Source: https://github.com/nimiq/core-rs-albatross/commit/807ee8e99a7ccdc604d49971f292854bfa36754d
// Patch in keys/src/tagged_signing.rs - replaces the panicking unwrap with proper error handling
impl TaggedPublicKey for Ed25519PublicKey {
fn verify(&self, msg: &[u8], sig: &[u8]) -> bool {
- self.verify(&Ed25519Signature::from_bytes(sig).unwrap(), msg)
+ let Ok(signature) = Ed25519Signature::from_bytes(sig) else {
+ return false;
+ };
+
+ self.verify(&signature, msg)
}
}
#[cfg(test)]
mod tests {
#[test]
fn tagged_verify_rejects_invalid_signature_lengths() {
let keypair = KeyPair::generate(&mut test_rng(false));
let message = b"test message";
let signature = keypair.sign(message);
// verify must now return cleanly on malformed lengths instead of panicking
}
}
Source: GitHub Commit 807ee8e
Detection Methods for CVE-2026-40092
Indicators of Compromise
- Unexpected Nimiq node process termination with a Rust panic message referencing Ed25519Signature::from_bytes or unwrap() on a Result::Err
- Stack traces in node logs pointing to tagged_signing.rs inside the keys crate during DHT record verification
- Inbound Kademlia DHT records containing TaggedSigned payloads with signature fields of length other than 64 bytes
Detection Strategies
- Parse node stdout/stderr for panic strings such as called \Result::unwrap()` on an `Err` valuecorrelated with thetagged_signing` module
- Monitor crash-restart cycles on validator and full nodes, especially when multiple peers crash within a short window
- Inspect captured DHT traffic for ValidatorRecord entries whose signature blobs deviate from the 64-byte Ed25519 length
Monitoring Recommendations
- Alert on process exit codes from nimiq-client and related binaries that indicate panic-induced termination
- Track peer-to-peer churn metrics for sudden spikes in node disconnects following DHT gossip events
- Forward node logs to a central log store and create rules for the tagged_signing panic signature
How to Mitigate CVE-2026-40092
Immediate Actions Required
- Upgrade all Nimiq full nodes and validators running core-rs-albatross to version 1.4.0 or later without delay
- Restart any nodes currently crash-looping and confirm the patched binary is loaded before rejoining the network
- Review peer logs to identify the source of any malformed DHT records and consider denylisting persistent offenders
Patch Information
The fix is included in core-rs-albatross v1.4.0. The patch in pull request 3708 replaces Ed25519Signature::from_bytes(sig).unwrap() with a let-else pattern that returns false when deserialization fails, mirroring the existing BLS behavior. See the GitHub Release v1.4.0 and Security Advisory GHSA-27w2-87xv-37c6 for full details.
Workarounds
- No supported runtime workaround exists; upgrading to v1.4.0 is the only complete remediation
- Operators unable to upgrade immediately can run nodes behind a supervisor that automatically restarts on panic to reduce downtime, accepting that repeated crashes will continue
- Restrict inbound peer connections to a vetted allowlist of trusted nodes to lower exposure until patching completes
# Upgrade core-rs-albatross to the patched release
git clone https://github.com/nimiq/core-rs-albatross.git
cd core-rs-albatross
git checkout v1.4.0
cargo build --release --bin nimiq-client
# Verify the running binary version before restarting the node
./target/release/nimiq-client --version
systemctl restart nimiq-client
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


