首页 / 漏洞库
参考

智能合约漏洞库

逐一讲解每类漏洞,附带有漏洞的示例及其修复版本。

重入(Reentrancy)

在更新状态之前进行的外部调用,会让攻击者在余额被扣减前重新进入该函数。请遵循 checks-effects-interactions 并使用重入保护。

// vulnerable
function withdraw(uint a) public {
  require(bal[msg.sender] >= a);
  (bool ok,) = msg.sender.call{value:a}("");
  bal[msg.sender] -= a; // too late
}
// fixed
function withdraw(uint a) public nonReentrant {
  require(bal[msg.sender] >= a);
  bal[msg.sender] -= a;                 // effects first
  (bool ok,) = msg.sender.call{value:a}("");
  require(ok);
}

使用 tx.origin 鉴权

tx.origin 做授权会让中间合约以用户名义行事。请使用 msg.sender

预言机 / 价格操纵

从单一资金池读取现货价格会使其可被大额兑换操纵,通常由闪电贷提供资金。优先使用时间加权平均价(TWAP)或聚合预言机。

缺失访问控制

没有限制修饰符的敏感函数可被任何人调用。用 onlyOwner 或角色检查来保护特权函数。

未检查的外部调用

忽略低级调用的返回值会让合约在转账失败后继续执行。务必检查返回的布尔值。

业务逻辑缺陷

反转的比较或错误的份额计算会破坏不变量。这些缺陷是合约特有的,会逃过通用检测器,且往往代价最高。描述预期行为并与代码对比。

想在安全环境中练习利用这些漏洞?见 学习。准备好扫描你自己的合约了吗?打开扫描器

▶ 打开扫描器