code4rena-2024-08-chakra-h14

[H-14] Malicious actors can manipulate the cross_chain_callback callback

보고서

Summary

파라미터를 서명으로 검증하지 않아 공격자가 트랜잭션을 프론트러닝하여 동일 서명을 사용하며 다른 파라미터로 호출할 수 있다. 이로 인해 공격자가 메시지 전달 결과를 Failed 로 기록하여 정상 처리를 방해할 수 있다.

Keyword

bridge, cross chain, signature, dos, input validation

Vulnerability

receive_cross_chain_callback 함수는 메시지를 보냈던 목적지 체인에서의 실행 결과를 돌려받는 함수이다. 목적지 체인에서의 작업 성공 여부를 보고받는다.

이 함수의 from_chain 파라미터는 서명을 통해 인증되지 않는다. 따라서 임의의 from_chain 으로 변경하여 호출할 수 있다.

function receive_cross_chain_callback(
    uint256 txid,
@>  string memory from_chain,
    uint256 from_handler,
    address to_handler,
    CrossChainMsgStatus status,
    uint8 sign_type,
    bytes calldata signatures
) external {
@>  verifySignature(
        txid,
        from_handler,
        to_handler,
        status,
        sign_type,
        signatures
    );
    processCrossChainCallback(
        txid,
        from_chain,
        from_handler,
        to_handler,
        status,
        sign_type,
        signatures
    );
    emitCrossChainResult(txid);
}
 
function verifySignature(
    uint256 txid,
    uint256 from_handler,
    address to_handler,
    CrossChainMsgStatus status,
    uint8 sign_type,
    bytes calldata signatures
) internal view {
    bytes32 message_hash = keccak256(
@>      abi.encodePacked(txid, from_handler, to_handler, status)
    );
 
    require(
        signature_verifier.verify(message_hash, signatures, sign_type),
        "Invalid signature"
    );
}

공격자는 정상 트랜잭션을 프론트러닝하여 공격할 수 있다. 정상 트랜잭션의 서명을 이용하고, from_chain을 다르게 설정했을 때 서명 확인은 통과할 수 있다. 이후 호출되는 processCrossChainCallback에서 핸들러의 receive_cross_chain_callback를 호출하는데, 이 함수는 from_chainfrom_handler 가 등록되어 있지 않다면 false를 리턴한다.

function receive_cross_chain_callback(
    ...
) external onlySettlement returns (bool) {
    //  from_handler need in whitelist
@>  if (is_valid_handler(from_chain, from_handler) == false) {
        return false;
    }

receive_cross_chain_callbackfalse를 리턴하면 해당 메시지의 전달 결과는 Failed 로 기록된다.

function processCrossChainCallback(
    uint256 txid,
    string memory from_chain,
    uint256 from_handler,
    address to_handler,
    CrossChainMsgStatus status,
    uint8 sign_type,
    bytes calldata signatures
) internal {
    require(
        create_cross_txs[txid].status == CrossChainMsgStatus.Pending,
        "Invalid transaction status"
    );
 
    if (
@>      ISettlementHandler(to_handler).receive_cross_chain_callback(
            txid,
            from_chain,
            from_handler,
            status,
            sign_type,
            signatures
        )
    ) {
        create_cross_txs[txid].status = status;
    } else {
@>      create_cross_txs[txid].status = CrossChainMsgStatus.Failed;
    }
}

Impact

공격자가 메시지 전달 결과를 Failed 로 기록하여 정상 처리를 방해할 수 있다.

Mitigation

from_chain 도 서명으로 확인한다.


tags: bughunting, chakra, smart contract, solidity, bridge, cross chain, severity high, signature, dos, lack-of-input-validation-vul