跳到主要内容

访问控制漏洞

智能合约的访问控制漏洞是导致 Poly Network 跨链桥黑客攻击(损失 6.11 亿美元)的主要因素之一,并且也导致了在币安智能链(BSC)上的 ShadowFi DeFi 项目遭受 30 万美元的黑客攻击。

以下两篇文章提供了这些攻击事件详细情况的更多洞见:

智能合约中的访问控制定义了应用内不同角色的权限。 通常,像铸造代币、提取资金或暂停交易等操作需要用户拥有更高权限。 这些权限配置不当可能导致意外损失。

下面,我们将讨论两种常见的访问控制漏洞类型。

1. 权限配置错误

缺乏对关键函数适当的访问控制,允许任何人铸造大量代币或从合约中提取所有资金。 例如,Poly Network 桥合约未能限制转移监护权的功能,允许黑客将 6.11 亿美元重定向到他们自己的地址。

在下面的代码中,flawedCreateToken() 函数缺乏访问限制,允许任何用户无限制地铸造代币。

// Flawed createToken function without access control
function flawedCreateToken(address recipient, uint256 quantity) public {
_mint(recipient, quantity);
}

2. 授权检查漏洞

另一个常见的漏洞是,函数不验证调用者是否具有足够的权限。 例如,ShadowFi 在 BSC 上的代币合约省略了其 burn 功能中的一个关键检查,允许攻击者随意燃烧其他地址拥有的代币。 在燃烧流动性池中的代币后,黑客通过出售最少量的代币,便可以从池中提取所有的 BNB,获利 30 万美元。

在给出的代码片段中,flawedDestroyToken() 函数未实现必要的授权检查,因此允许任何用户无限制地燃烧代币。

// Flawed destroyToken function without proper authorization checks
function flawedDestroyToken(address holder, uint256 quantity) public {
_burn(holder, quantity);
}

预防策略

预防访问控制漏洞的两个主要策略是:

  1. 使用像 OpenZeppelin 这样的访问控制库来为特殊函数分配适当的权限,例如使用 OnlyOwner 修饰符来限制只有合约所有者才能调用函数。
// Correct createToken function using the onlyOwner modifier for access control
function correctCreateToken(address recipient, uint256 quantity) public onlyOwner {
_mint(recipient, quantity);
}
  1. 确保函数逻辑验证调用者是否具有必要的权限。
// Correct destroyToken function with authorization check
function correctDestroyToken(address holder, uint256 quantity) public {
if(msg.sender != holder){
_spendAllowance(holder, msg.sender, quantity);
}
_burn(holder, quantity);
}