Solidity 智能合约安全漏洞——跨合约重入攻击

跨合约重入攻击

概述

跨合约重入性是指在智能合约之间发生的重入攻击,这种攻击不仅限于单一合约内部的函数调用,还可能涉及多个合约,尤其是当这些合约共享相同的状态变量时。在跨合约重入攻击中,如果状态更新不是在外部调用之前完成,那么重入可能导致严重的安全漏洞。

漏洞成因

跨合约重入通常发生在多个合约共享同一状态变量,并且其中一些合约在更新这些变量时存在安全隐患。由于涉及多个合约和共享状态,这种类型的重入问题可能更加复杂且难以发现。

漏洞示例

考虑以下简化的示例,涉及两个合约:一个银行合约和一个交易合约,它们共享一个状态变量来记录用户余额。

银行合约

contract Bank {
    
    
    mapping(address => uint) public balances;

    function deposit() public payable {
    
    
        balances[msg.sender] += msg.value;
    }

    function withdraw(address to, uint amount) public {
    
    
        require(balances[to] >= amount, "Insufficient funds");
        (bool success, ) = to.call{
    
    value: amount}("");
        require(success, "Transfer failed");
        balances[to] -= amount;
    }
}

交易合约

contract Trader {
    
    
    Bank bank;

    constructor(address _bank) {
    
    
        bank = Bank(_bank);
    }

    function exploitWithdrawal(address to) public {
    
    
        bank.withdraw(to, 100);
    }
}

攻击过程

在这个场景中,如果 Trader 合约中的 exploitWithdrawal 方法能够在 Bank 合约的 withdraw方法的外部调用完成前被重入,那么可能会在Bank合约的状态更新(即balances[to] -= amount)之前多次提取资金,重入流程如下:

请添加图片描述

防范措施

防止跨合约重入的有效方法之一依旧是使用 Checks-Effects-Interactions(检查-效果-交互)模式,即首先进行所有必要的状态检查(Checks),然后更新状态(Effects),最后执行任何外部交互(Interactions)。

猜你喜欢

转载自blog.csdn.net/qq_69584919/article/details/141344969