SWC智能合约漏洞库

在线工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器

SWC-113/失败调用引发的DoS攻击

外部呼叫可能会偶然或故意失败,从而引发合约出现DoS。为了最大程度地减少此类故障造成的损害, 最好将每个外部呼叫隔离到自己的交易中,该交易可以由呼叫的接收者发起。这与支付特别相关, 在这种情况下,最好让用户提取资金,而不是自动将资金推送到他们(这也减少了gaslimit出现问题的机会)。

CWE漏洞分类

CWE-703:不当处理特殊情况

整改方案

建议遵循调用合约的最佳做法:

  • 避免在单一交易中合并多个调用,尤其是当调用作为循环的一部分执行时
  • 始终假设外部呼叫可能失败
  • 实现失败调用的处理逻辑

参考文献

示例合约

send_loop.sol

/*
 * @source: https://consensys.github.io/smart-contract-best-practices/known_attacks/#dos-with-unexpected-revert
 * @author: ConsenSys Diligence
 * Modified by Bernhard Mueller
 */

pragma solidity 0.4.24;

contract Refunder {

address[] private refundAddresses;
mapping (address => uint) public refunds;

    constructor() {
        refundAddresses.push(0x79B483371E87d664cd39491b5F06250165e4b184);
        refundAddresses.push(0x79B483371E87d664cd39491b5F06250165e4b185);
    }

    // bad
    function refundAll() public {
        for(uint x; x < refundAddresses.length; x++) { // arbitrary length iteration based on how many addresses participated
            require(refundAddresses[x].send(refunds[refundAddresses[x]])); // doubly bad, now a single failure on send will hold up all funds
        }
    }

}

send_loop.yaml

description: Send called in a loop
issues:
- id: SWC-113
  count: 1
  locations:
  - bytecode_offsets:
      '0x0740310f63ff97d41fdc9170b44535586a824d54c710dd0e9f75d7103bf71ce8': [431]
    line_numbers:
      send_loop.sol: [21, 22, 23]