From 77bf4419e0465c7455eee2646b8e09ff2e38ad18 Mon Sep 17 00:00:00 2001 From: Uncle Stinky Date: Sat, 26 Sep 2026 14:30:22 +0300 Subject: [PATCH] prevent exploit via compute_arguments_hash bypass Signed-off-by: Uncle Stinky --- pallets/weaver/Cargo.toml | 2 +- pallets/weaver/src/types.rs | 22 +++++++++------------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/pallets/weaver/Cargo.toml b/pallets/weaver/Cargo.toml index f474738..3b72278 100644 --- a/pallets/weaver/Cargo.toml +++ b/pallets/weaver/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ghost-weaver" -version = "0.0.14" +version = "0.0.15" description = "Weaving a secure cryptographic tapestry across different external chains." license.workspace = true authors.workspace = true diff --git a/pallets/weaver/src/types.rs b/pallets/weaver/src/types.rs index dab7402..b9a2624 100644 --- a/pallets/weaver/src/types.rs +++ b/pallets/weaver/src/types.rs @@ -14,7 +14,6 @@ use ghost_helpers::{ merkle_tree::verify_tree_proof, SubstrateBlake2Hasher, SubstrateKeccakHasher, UtxoSha2Hasher, }; -use ghost_traits::hashing::GhostHasher; use crate::{ExternalBlockNumber, ThreadId, WeavingSession}; @@ -350,8 +349,10 @@ where { if EVM_MERKLE_DEPTH as usize != self.proof.len() { return None; } + let preimage_hash = self.get_preimage_hash(network_id)?; + let proof_valid = verify_tree_proof::( - &self.get_preimage_slice(network_id).to_fixed_bytes(), + &preimage_hash.to_fixed_bytes(), self.proof.as_ref(), root_hash, self.proof_index, @@ -362,22 +363,17 @@ where Some((self.receiver.clone(), self.amount)) } - fn get_preimage_slice(&self, network_id: NetworkId) -> H256 + fn get_preimage_hash(&self, network_id: NetworkId) -> Option where NetworkId: Copy + Clone + Eq + PartialEq + UniqueSaturatedInto, { let slot_index_usize: usize = self.slot_index.unique_saturated_into(); - let mut slot_values: Vec = self.slots.to_vec(); - match slot_values.get_mut(slot_index_usize) { - Some(slot) => { - *slot = self.compute_arguments_hash(network_id); - cumulative_hash::(slot_values) - } - None => { - SubstrateKeccakHasher::empty() - } - } + self.slots.get(slot_index_usize) + .filter(|&&provided_hash| { + provided_hash == self.compute_arguments_hash(network_id) + }) + .map(|_| cumulative_hash::(self.slots.iter())) } pub fn get_unique_key(