访问控制漏洞
智能合约的访问控制漏洞是导致 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);
}
预防策略
预防访问控制漏洞的两个主要策略是:
- 使用像
OpenZeppelin 这样的访问控制库来为特殊函数分配适当的权限,例如使用
OnlyOwner
修饰符来限制只有合约所有者才能调用函数。
// Correct createToken function using the onlyOwner modifier for access control
function correctCreateToken(address recipient, uint256 quantity) public onlyOwner {
_mint(recipient, quantity);
}
- 确保函数逻辑验证调用者是否具有必要的权限。
// 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);
}