Submitted by Moksha, also found by Abdessamed, aldarion, ABAIKUNANBAEV, 0xAsen, Tigerfrake, 0x37, blackpanther, mjcpwns, kutugu, pwnforce, avoloder, Audinarey, jasonxiale, Daniel_eth, SBSecurity, 0xNirix, Emmanuel, Respx, tekkac, peanuts, b0g0, LuarSec, haxatron, klau5, said, shaflow2, Shaheen, mojito_auditor, fyamf, devival, ZdravkoHr, Drynooo, Agontuk, AllTooWell, and PASCAL
The impact is high as the adversary can call the receive_cross_chain_msg with the already processed and valid parameters and benefit from it. With such parameters, anyone can call not just the validators so it further affects the protocol. Due to the missing check if the txId status is UNKNOW the attack is very much feasible as shown in the below fork testing local POC. This also breaks the main invariant mentioned in the audit docs/readme that
Below is the fork testing locally test case snippet and steps where the already deployed contract addresses on the Sepolia testnet of Starknet are used due to the nature of the bug, the attacker needs to resubmit the already processed, valid message and signatures of valid/whitelisted operators too. The sponsors have provided a notion document on the audit details page from where the contract address and other details were obtained.
Such details provided by the sponsor can be found here.
The contract address mentioned there is a bit old and got upgraded a few times and deployed new ones too so below code snippet below has the latest one.
Step 1: Get the deployed settlement_handler.cairo contract address.
This is the latest one deployed on the sepolia test net starknet chain: https://sepolia.starkscan.co/contract/0x0449f7dae3a8073aeee71a7203467d686a5227d90a9149a524787ccb0f5de54f#read-write-contract-sub-write
Step 2: Already made call receive_cross_chain_msg to Step 1 contract with necessary parameters like txId, signatures (important), etc. Which succeed too i.e. that returned the true
This is the call: https://sepolia.starkscan.co/call/0x03842b8ffb248e0d2f629828c3af83ff718de72be67b3a6a5acf191ad95f4706_1_1
The mint/transfer event for the same above call
https://sepolia.voyager.online/event/163813_0_0
Call Overview
The call is from the Chakra chain to starknet and the payload says to transfer the chakraBTC (handler/btc.cairo) deployed on the testnet chain. In the next step, we would take the same parameter for the chain locally call the receive_cross-chain_msg multiple times, and observe the balance increase for the address in this payload. According to the payload, the address to receive is 0x8e0202cd048b6ccb8aa36d5d00ed0aa9b6d9e088 and the amount is 130000 of chakraBTC.
Step 3: Forking the chain to again call the receive_cross_chain_msg to settlement_handler contract we got in Step 1.
Add the following into the cairo/handler/Scarb.toml
Paste the following test snippet in the cairo/handler/src/tests/test_settlement.cairo.
Tool version is same as sponsors snforge: v0.20.0
Run the snforge test.
The test case passes and the balance of the receiver does the increase by 130000 every time we call with the same parameters.
Evident from the code the receive_cross_chain_msg function in handler/settlement.cairo function lacks the validation or invariant mentioned of CrossChainMsgStatus.Unknow thus leads to process the already processed valid message again and again resulting in loss to the protocol https://github.com/code-423n4/2024-08-chakra/blob/d0d45ae1d26ca1b87034e67180fac07ce9642fd9/cairo/handler/src/settlement.cairo#L325-L383
Add check in the receive_cross_chain_msg handler/settlement.cairo to check the cross chain status of the txid.
zvlwwj (Chakra) confirmed via duplicate issue #131
0xsomeone (judge) commented:
