SWC智能合约漏洞库

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

SWC-112/委托调用非可信合约

delegatecall是一个消息调用的特殊变体,它类似于消息调用,不同之处在于目标地址上的代码 是在调用合约的上下文中执行的,msg.sender和msg.value保持不变。这允许智能合约在运行时 从其他地址动态加载代码。存储空间、当前地址和余额仍参考主叫合约。

调用不受信任的合约非常危险,因为目标地址上的代码可以更改调用者的任何存储值,并且可以 完全控制调用者的余额。

CWE漏洞分类

CWE-829:包含不受信任域的功能

整改方案

请谨慎使用delegatecall,并确保切勿调用不受信任的合约。如果目标地址来自用户输入,请确保 使用受信任合约白名单进行检查。

参考文献

示例合约

proxy.sol

pragma solidity ^0.4.24;

contract Proxy {

  address owner;

  constructor() public {
    owner = msg.sender;  
  }

  function forward(address callee, bytes _data) public {
    require(callee.delegatecall(_data));
  }

}

proxy.yaml

description: Simple proxy pattern with delegatecall
issues:
- id: SWC-112
  count: 1
  locations:
  - bytecode_offsets:
      '0x0cacc6a10a08e1bfafa8d8feca0d1e899b99bdc57b8455840e21c19db6665bfc': [337]
    line_numbers:
      proxy.sol: [12]

proxy_fixed.sol

pragma solidity ^0.4.24;

contract Proxy {

  address callee;
  address owner;

  modifier onlyOwner {
    require(msg.sender == owner);
    _;
  }

  constructor() public {
    callee = address(0x0);
    owner = msg.sender;
  }

  function setCallee(address newCallee) public onlyOwner {
    callee = newCallee;
  }

  function forward(bytes _data) public {
    require(callee.delegatecall(_data));
  }

}

proxy_fixed.yaml

description: Simple proxy pattern with delegatecall (fixed)
issues:
- id: SWC-112
  count: 0
  locations: []

proxy_pattern_false_positive.sol

pragma solidity ^0.4.24;

contract proxy{
  address owner;

  function proxyCall(address _to, bytes _data) external {
    require( !_to.delegatecall(_data));
  }
  function withdraw() external{
    require(msg.sender == owner);
    msg.sender.transfer(address(this).balance);
  }
} 

/*
You can't use proxyCall to change the owner address as either: 

1) the delegatecall reverts and thus does not change owner
2) the delegatecall does not revert and therefore will cause the proxyCall to revert and preventing owner from changing

This false positive may seem like a really edge case, however since you can revert data back to proxy this patern is useful for proxy architectures
*/

proxy_pattern_false_positive.yaml

issues:
- id: SWC-112
  count: 0
  locations: []