code4rena-2024-08-chakra-h03
[H-03] SettlementSignatureVerifier is missing check for duplicate validator signatures
Summary
서명을 확인할 때 중복된 서명이 있는지 확인하지 않았다. Solidity와 Cairo 양쪽에 서명 확인 기능이 있었는데 양쪽 모두 이슈가 있었다. 이 취약점으로 인해 한 명의 밸리데이터 만으로 인증하여 잠겨있는 모든 토큰을 꺼내가거나 민팅, 소각할 수 있다.
Keyword
bridge, cross chain, lack of input validation, signature, theft
Vulnerability
- solidity/handler/contracts/SettlementSignatureVerifier.sol#L134
- solidity/settlement/contracts/SettlementSignatureVerifier.sol#L207
- cairo/handler/src/settlement.cairo#L178-L189
Solidity에서, verifyECDSA 에서 서명을 확인할 때 중복된 서명이 있는지 확인하지 않는다. 단지 서명자가 validator로 등록되어 있는지만 확인한다. 이 함수를 호출하는 verify 함수나 verify 를 호출하는 함수 역시 중복된 서명이 있는지 확인하지 않는다. 따라서 validator 한 명의 서명으로도 verify 할 수 있다. Validator는 receive_cross_chain_msg 를 자유롭게 호출하여 토큰을 꺼내가거나 민팅받을 수 있다. 또한 receive_cross_chain_callback 를 호출하여 토큰을 소각시킬 수 있다.
function verifyECDSA(
bytes32 msgHash,
bytes calldata signatures
) internal view returns (bool) {
require(
signatures.length % 65 == 0,
"Signature length must be a multiple of 65"
);
uint256 len = signatures.length;
uint256 m = 0;
for (uint256 i = 0; i < len; i += 65) {
bytes memory sig = signatures[i:i + 65];
if (
@> validators[msgHash.recover(sig)] && ++m >= required_validators
) {
return true;
}
}
return false;
}Cairo에서, check_chakra_signatures 함수에서 서명을 확인할 때, 서명이 중복되었는지는 확인하지 않는다. 따라서 한 명의 Validator 서명 만으로 verify 할 수 있다. Validator는 receive_cross_chain_msg 를 자유롭게 호출하여 토큰을 꺼내가거나 민팅받을 수 있다. 또한 receive_cross_chain_callback 를 호출하여 토큰을 소각 시킬 수 있다.
#[generate_trait]
impl InternalImpl of InternalTrait {
// validate signatures should > required_validators_num
// @param message_hash the perdsen hash of message
// @param the signatures corresponding to each verifier
fn check_chakra_signatures(
self: @ContractState, message_hash: felt252, signatures: Array<(felt252, felt252, bool)>
){
let mut pass_count = 0;
let mut i = 0;
loop {
if i > signatures.len()-1{
break;
}
let (r,s,y) = * signatures.at(i);
let pub_key: felt252 = recover_public_key(message_hash,r,s,y).unwrap();
@> if self.chakra_validators_pubkey.read(pub_key) > 0{
@> pass_count += 1;
}
i += 1;
};
@> assert(pass_count >= self.required_validators_num.read(), 'Not enough validate signatures');
}
}Impact
이 취약점으로 인해 한 명의 밸리데이터 만으로 인증하여 잠겨있는 모든 토큰을 꺼내가거나 민팅, 소각할 수 있다.
Mitigation
Solidity에서, verifyECDSA 에서 서명을 확인한 주소를 기록하고, 중복이 있다면 트랜잭션을 취소 시킨다.
Cairo에서, check_chakra_signatures 에서 서명을 확인한 주소를 기록하고, 중복이 있다면 트랜잭션을 취소 시킨다.
tags: bughunting, chakra, smart contract, starknet, cairo, solidity, crypto theft, bridge, cross chain, signature, severity high