经典重入攻击案例分享及解析

什么是重入攻击重入攻击(ReentrancyAttack)?要如何解决并避免类似的问题?

什么是重入攻击

重入攻击(Reentrancy Attack)是一种智能合约安全漏洞,攻击者利用合约对外部地址调用时的回调函数,在状态变量更新之前反复调用合约,从而重复执行提款或转账操作,导致资金被盗。

案例解析

function claimToken(address tokenAddress) external {
    require(tokenAddress != address(0), "Invalid token address");
    uint256 rewardAmount = userRewardAmounts[msg.sender][tokenAddress];
    require(rewardAmount > 0, "No reward available");
    if (tokenAddress == ethAddress) {
        (bool success, ) = msg.sender.call{value: rewardAmount}("");
        require(success, "ETH transfer failed");
    } else {
        IERC20(tokenAddress).safeTransfer(msg.sender, rewardAmount);
    }
    userRewardAmounts[msg.sender][tokenAddress] = 0;
    tokenBalances[tokenAddress] -= rewardAmount;
}

这种顺序会导致以下问题:

  • 当转账是ETH时,使用call进行低级别调用,接收者可以通过fallbackreceive函数触发重入;
  • 当转账是ERC20 代币时,虽然使用了safeTransfer(通常是安全的),但如果代币实现了恶意逻辑(如回调),仍可能被利用。

如何实现攻击: 假设攻击者的合约Attacker作为接收者:

  1. 调用claimToken请求领取 100 ETH 奖励;
  2. 合约转账 100 ETH 到Attacker
  3. Attackerreceive函数被触发,立即再次调用claimToken
  4. 由于状态尚未更新(userRewardAmounts仍为 100),合约会再次转账 100 ETH;
  5. 重复步骤 3-4,直到合约 ETH 耗尽。

解决方案

使用 检查 - 效果 - 交互(Checks-Effects-Interactions) 模式,先更新状态再进行资金转移:

function claimToken(address tokenAddress) external {
    require(tokenAddress != address(0), "Invalid token address");

    // 1. 检查:读取奖励金额
    uint256 rewardAmount = userRewardAmounts[msg.sender][tokenAddress];
    require(rewardAmount > 0, "No reward available");

    // 2. 效果:立即更新状态(重置奖励和减少余额)
    userRewardAmounts[msg.sender][tokenAddress] = 0;
    tokenBalances[tokenAddress] -= rewardAmount;

    // 3. 交互:最后进行资金转移
    if (tokenAddress == ethAddress) {
        (bool success, ) = msg.sender.call{value: rewardAmount}("");
        require(success, "ETH transfer failed");
    } else {
        IERC20(tokenAddress).safeTransfer(msg.sender, rewardAmount);
    }
}

总结

重入攻击是“先转账后记账”导致的经典漏洞,需通过状态优先更新锁机制彻底防御。

  • 重入攻击的核心:外部调用(calltransfersend)可能触发恶意回调。
  • 核心问题是资金转移先于状态更新。修复方案是调整执行顺序,先更新状态再转账
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
mengbuluo222
mengbuluo222
0x9Ff1...FaA5
前端开发求职中... 8年+开发经验,拥有丰富的开发经验,擅长VUE、React开发。