Assessment reports>Hyperlane Starknet>High findings>Multisig ISM allows duplicated signatures
Category: Coding Mistakes

Multisig ISM allows duplicated signatures

High Severity
High Impact
High Likelihood

Description

Multisig ISM in the Hyperlane protocol is an Interchain Security module (ISM) that returns true when the signatures of m-of-n validators are provided, where the threshold and the list of validators are predetermined. It is implemented in merkleroot_multisig_ism.cairo and messageid_multisig_ism.cairo:

fn verify(self: @ContractState, _metadata: Bytes, _message: Message,) -> bool {
    assert(_metadata.clone().size() > 0, Errors::EMPTY_METADATA);
    let digest = self.digest(_metadata.clone(), _message.clone());
    let (validators, threshold) = self.validators_and_threshold(_message);
    assert(threshold > 0, Errors::NO_MULTISIG_THRESHOLD_FOR_MESSAGE);
    let mut i = 0;
    // for each couple (sig_s, sig_r) extracted from the metadata
    loop {
        if (i == threshold) {
            break ();
        }
        let signature = self.get_signature_at(_metadata.clone(), i);
        // we loop on the validators list public key in order to find a match
        let mut cur_idx = 0;
        let is_signer_in_list = loop {
            if (cur_idx == validators.len()) {
                break false;
            }
            let signer = *validators.at(cur_idx);
            if bool_is_eth_signature_valid(digest, signature, signer) {
                // we found a match
                break true;
            }
            cur_idx += 1;
        };
        assert(is_signer_in_list, Errors::NO_MATCH_FOR_SIGNATURE);
        i += 1;
    };
    true
}

However, this code allows a signature from one validator to be accepted more than once.

Impact

A malicious relayer who can obtain a signature of one validator can make the Multisig ISM return true by submitting the signature from one validator multiple times.

Recommendations

Consider ensuring that given signatures are not duplicated.

Remediation

This issue has been acknowledged by Pragma, and a fix was implemented in commit ac648a31.

Zellic © 2025Back to top ↑