75979 bc medium compute message id decompresses every incoming gossip message via snap raw decoder decompress vec without enforcing the documented decompressed size cap allowing per messa
Description
Brief/Intro
Vulnerability Details
// base/crates/consensus/gossip/src/config.rs:14-15
/// The maximum gossip size.
/// Limits the total size of gossip RPC containers as well as decompressed individual messages.
pub const MAX_GOSSIP_SIZE: usize = 10 * (1 << 20);
// base/crates/consensus/gossip/src/config.rs:104-122
/// Computes the [`MessageId`] of a [`gossipsub`] message.
fn compute_message_id(msg: &Message) -> MessageId {
let mut decoder = Decoder::new();
let id = decoder.decompress_vec(&msg.data).map_or_else(
|_| {
warn!(target: "cfg", "Failed to decompress message, using invalid snappy");
let domain_invalid_snappy: Vec<u8> = vec![0x0, 0x0, 0x0, 0x0];
sha256([domain_invalid_snappy.as_slice(), msg.data.as_slice()].concat().as_slice())
[..20]
.to_vec()
},
|data| {// data may be GiB-sized
let domain_valid_snappy: Vec<u8> = vec![0x1, 0x0, 0x0, 0x0];
sha256([domain_valid_snappy.as_slice(), data.as_slice()].concat().as_slice())[..20]
.to_vec()
},
);
MessageId(id)
}Impact Details
References
Proof of Concept
Why the body is [0x00, 0x42]
Why 100 MiB rather than 4 GiB
Required workspace config workaround
1
2
Build & run
Recorded run logs
Previous74351 sc low bond permanently locked after zk verifier nullification in proof threshold 2 gameNext75502 sc low nullified zk verifier does not invalidate prior zk games allowing invalid roots to finalize after a soundness alert
Was this helpful?