OWASP智能合约Top 10 2026:变更与审计指南

  • zealynx
  • 发布于 3 天前
  • 阅读 24

OWASP 发布了智能合约安全 Top 10 2026 版本,基于 122 起 2025 年事故(约 9.05 亿美元损失)重新排序。业务逻辑漏洞升至第二,新增代理与升级漏洞(第十),重入攻击降至第八。文章详细分析了每个类别的定义、真实案例及审计方法,强调组合攻击(如闪电贷+预言机操纵+业务逻辑缺陷)和不变性测试的重要性。

OWASP 智能合约安全项目已发布 2026 年智能合约 Top 10,这并非对 2025 年清单的简单刷新。该框架已重新锚定至 2025 年发生的 122 起独立事件,这些事件造成了约 9.05 亿美元的纯合约损失,其中两项结构性变更比其余变更更重要:业务逻辑漏洞提升至 SC02:2026,代理与可升级性漏洞则是一个全新类别,位居 SC10:2026。重入攻击——十年来定义 Solidity 审计文化的漏洞类别——已从第 2 位降至第 8 位。

如果你将这三大变更联系起来看,该框架正在告诉你一些关于协议在 2025/2026 年实际失效方式的特定信息:单一向量攻击很少见。默认的攻击链现在变成:闪电贷提供对抗性资本 → 预言机操纵扭曲参考价格 → 业务逻辑缺陷允许抵押不足的操作 → 未检查的外部调用或代理弱点完成资产提取。孤立来看,每一步都能通过审查,但组合起来却违反了一个从未被声明的恒等式。

本文以一手资料描述、2025/2026 年的真实事件以及审计时的应对方式来逐一解说 2026 清单中的每个类别。对于 Zealynx 已有公开素材的类别,我们会提供链接;对于没有的类别,我们会明确说明。

TL;DR

  • 2026 年 OWASP 智能合约 Top 10 根据协议实际失效方式重新排序。访问控制 (SC01)、业务逻辑 (SC02)、预言机操纵 (SC03) 以及闪电贷放大的组合攻击 (SC04) 现已成为前四大类别。代理与可升级性已作为 SC10 新增。
  • 重入攻击从第 2 位降至第 8 位,因为工具和模式已经成熟(ReentrancyGuardReentrancyGuardTransient 几乎普遍使用,Slither 和 Mythril 能可靠检测到经典重入)。该类别并未消失——跨合约和只读重入在 2025/2026 年的发现中仍然出现,以 Solv 的 ERC-3525 事件(270 万美元)为典型近期案例。
  • 业务逻辑升至第 2 位,因为恒等式崩溃和经济边缘案例缺陷现已成为单一协议中最大的损失来源。Yearn 的 yETH 池崩溃(约 900 万美元,2025 年 11 月)、Cetus(约 2.23 亿美元,2025 年 5 月)、Balancer V2 的 ComposableStablePool(约 1.2864 亿美元,2025 年 11 月)以及 Aave 的 5000 万美元滑点事件(2026 年 3 月)是 OWASP 引用的示例。
  • 代理与可升级性是新增类别,因为未初始化的 ERC1967 代理在 2025 年成为了一场运动。Kinto Protocol(155 万美元,2025 年 7 月)是被引用最多的案例;更广泛的未初始化代理自动化攻击导致了超过 1000 万美元的总损失。
  • 检测是结构性的,而非词法性的。2026 年清单对应的审计响应是恒等式测试、信任边界映射以及对高价值属性的形式化验证——而非逐类别的代码审查。

2026 年清单,按顺序排列

完整的 OWASP 智能合约 Top 10 2026,取自 官方 SCS 网站 以及 OWASP/www-project-smart-contract-top-10 仓库

排名 编号 标题
1 SC01:2026 访问控制漏洞
2 SC02:2026 业务逻辑漏洞
3 SC03:2026 价格预言机操纵
4 SC04:2026 闪电贷助长攻击
5 SC05:2026 缺乏输入验证
6 SC06:2026 未检查的外部调用
7 SC07:2026 算术错误(舍入与精度)
8 SC08:2026 重入攻击
9 SC09:2026 整数溢出与下溢
10 SC10:2026 代理与可升级性漏洞

OWASP 还明确将几个类别降级为 2026 年的“荣誉提名”:Permit 抢跑与 nonce DoS、抢跑与 MEV、跨链 MEV(Symbiosis 在 2025 年 8 月至 10 月间累计约 527 万美元)、通过 gas/循环/状态膨胀实现的通用 DoS、治理特定向量(闪电贷放大的投票、时间锁绕过)以及密码学与签名方案问题。这些仍然是真实的漏洞类别,但它们产生的 2025 年事件数量不足以取代前十名中的任何一项。

2025 年到 2026 年的变化

2025 年到 2026 年的变化

类别 2025 年排名 2026 年排名 Δ
访问控制 1 1
逻辑错误 → 业务逻辑漏洞 3 2 +1(已重命名并扩展)
价格预言机操纵 2 3 −1
闪电贷攻击 7 4 +3
缺乏输入验证 4 5 −1
未检查的外部调用 6 6
算术错误(舍入与精度) 7 新增(拆分出)
重入 5 8 −3
整数溢出与下溢 8 9 −1
不安全的随机性 9 移除
拒绝服务 10 移除
代理与可升级性漏洞 10 新增

两项结构性变更承载了本次修订的分量,在逐个类别讨论之前值得单独探讨。

为什么业务逻辑排名上升

2025 年的条目标题是“逻辑错误”。2026 年已重命名为“业务逻辑漏洞”并推至第二名。更名表明了范围扩展:它不再仅仅是不正确的条件语句或变量交换。OWASP 2026 年的框架涵盖了奖励与费用逻辑缺陷、资格与限额绕过、路径依赖的状态机以及跨模块或跨链假设。其统一特性是:每个单独的低级检查都通过——类型安全、重入保护、访问控制都正确应用——但协议仍然失败,因为所执行的规则与协议需要执行的规则不匹配。

以下三个 2025/2026 年的事件具体说明了这一点:

  • Yearn yETH(约 900 万美元,2025 年 11 月)。一个加权稳定币兑换池的定点迭代求解器被足够不平衡的添加和移除流动性调用强制进入了一个发散区间。乘积项 Π 坍缩为零,s 不变量从混合稳定币退化为常数之和。大约 2.35×10⁵⁶ 个 yETH LP 代币在没有抵押品支持的情况下被铸造。
  • Cetus Protocol(约 2.23 亿美元,2025 年 5 月 22 日)。Sui 上一个 u256 定点库中的 checked_shlw 溢出检查在结构上存在缺陷。将位移位超出类型容量并未中止。攻击者操纵了一个 liquidity 参数,使得 get_delta_a 计算静默溢出,并返回只需要一个单位的代币 A 来铸造一个巨大的 LP 头寸。多次审计——MoveBit、OtterSec、Zellic 在 2025 年 4 月——都审查过该协议;库级别的数值代码实际上不在审计范围之内。
  • Aave 5000 万美元滑点事件(2026 年 3 月)。一名交易者通过一个经由稀薄 SushiSwap 池路由的接口,将大约 5040 万 USDT 兑换为约 36000 个 AAVE。夹子(Sandwich)提取接近 4400 万美元。前端发出了警告。合约并未在协议层面执行额度上限。

这三个案例的共性是:代码执行了它所说的操作,而它所说的操作就是漏洞所在。这不是静态分析器能捕获的一类发现。

为什么代理与可升级性是新增类别

SC10:2026 的存在是因为未初始化的 ERC1967 代理在 2025 年成为了一场自动化运动。其模式是机械性的:部署者部署了一个 ERC1967Proxy 并打算在后续交易中调用 initialize。监控多条 EVM 链上新合约的机器人抢先初始化了该代理,嵌入了一个恶意实现中的休眠后门。合法的 initialize 随后要么回滚(或者更糟,被静默覆盖),协议启动,后门潜伏,然后实现被升级以进行资金抽干。Kinto Protocol(155 万美元,2025 年 7 月)是被引用最多的具体案例;该运动造成的总损失超过 1000 万美元。

OWASP 的 SC10 页面 将四个子问题分组:

  1. 升级和管理员角色劫持——谁可以更改实现,以及存储布局是否兼容。
  2. 初始化和重新初始化——未受保护的 initialize、缺失的 initializer 守卫、初始化抢跑。
  3. Delegatecall 上下文错误——msg.sendermsg.value 和存储上下文混乱。
  4. 存储布局冲突——代理与实现之间的槽位冲突、未预留的空白、缺少仅追加原则。

2025 年发布的 PROXION 研究发现大约 54% 的以太坊合约是代理,其中许多带有未经验证的实现。CRUSH 符号执行工作将超过 600 万美元归因于类型冲突错误,其中 V2 实现以与 V1 不同的方式重新解释了槽位 0。OWASP 的框架指出 SC10“通常与访问控制 (SC01) 重叠,但由于其系统性影响,值得单独关注”。这种重叠是真实的——代理管理员妥协就是访问控制——但可升级性特有的故障模式(存储布局、初始化、delegatecall 上下文)仅凭 SC01 无法充分覆盖,这就是 OWASP 单独划分出一个类别的原因。

为什么重入排名下降

重入下降了六个名次是因为防护措施已经成熟,而不是因为该漏洞类别已经解决。OpenZeppelin 的 ReentrancyGuard 几乎普遍使用;坎昆升级后的 ReentrancyGuardTransient 将保护的Gas成本降低了一个数量级;检查-生效-交互模式从第一天起就被教授;Slither、Mythril 和 Aderyn 能可靠检测到经典重入。在生产发现中仍然存在的是回调驱动的重入(ERC-721/1155/3525/777 Hook、ERC-4626 存款/取款Hook、闪电贷回调)以及只读重入——这种变体是视图函数在回调期间读取了过时的状态,即便没有状态变异的重入。Solv Protocol 的 ERC-3525 事件(270 万美元,2026 年)是典型的近期案例。该类别之所以仍保持在前十,正是因为这些变体仍然在发生。

SC01:2026 — 访问控制漏洞

定义。 访问控制漏洞是指未经授权的调用者调用特权函数或修改关键状态的情况。OWASP 2026 年的框架超越了 onlyOwner 修饰符,扩展到治理、升级权限以及整个管理信任图——包括信任图的链下组件。

示例:Bybit(2025 年 2 月 21 日,约 15 亿美元)。这是 OWASP 及后续评论中引用最多的案例研究,它之所以具有启发性,正是因为它看起来不像 Solidity 意义上的“访问控制错误”。根据 NCC Group、Sygnia、Verichains 和 BlockSec 的事后分析,签名者批准了他们 UI 显示为常规冷到热 ETH 转账的交易。攻击者此前已入侵一名 Safe{Wallet} 开发者的 macOS 工作站,获得了服务 app.safe.global JavaScript 的 AWS S3 存储桶的访问权限,并在 2 月 19 日替换了该脚本。当三位签名者在 2 月 21 日批准时,恶意脚本静默地将 calldata 重写为对攻击者控制代码的 delegatecall,将 Safe 的控制权转移给攻击者,随后攻击者盗走了约 401,347 ETH。硬件钱包盲目签名,因为它们无法解析被修改的 Safe 交易负载。

教训:访问控制不再是孤立的 Solidity 属性;它是从开发者笔记本电脑 → CI/CD → 前端脚本 → 签名者界面 → 链上函数选择器的整个链的属性。

检测方法。

  • 手动审查——枚举每个 external/public 函数并证明存在通往已记录角色的路径;验证所有管理地址都是多签 + 时间锁;检查所有权转移是否为两步(Ownable2Step 或等效方案);查找 tx.origin 的使用;查找实现上的 selfdestruct 暴露。
  • 工具——Slither 的 arbitrary-sendunprotected-upgradesuicidalincorrect-modifier 检测器是第一道防线;Aderyn 用于交叉检查;Halmos 用于符号化证明只有授权调用者才能到达状态变异。
  • 流程——对链下签名管道进行威胁建模;要求对原始 calldata 进行清晰签名,或者在支持该功能的硬件钱包上进行交易模拟。

Zealynx 覆盖。 2025 年漏洞利用教训文章详细讨论了 Bybit/Cetus/Balancer 案例。ERC-4337 六种故障模式文章涵盖了可编程账户的访问模式。DAO 治理攻击文章将访问控制表面扩展到协议治理。

SC02:2026 — 业务逻辑漏洞

定义。 根据 OWASP,业务逻辑漏洞是指即使每个单独的低级检查都是正确的,智能合约的预期经济或功能行为仍然可以被颠覆的情况。该类别分为四个子类:

  1. 奖励与费用逻辑缺陷(重复计算、错误的受益人、计算错误的应计)。
  2. 资格与限额绕过(借款限额、铸造限额、清算阈值)。
  3. 路径依赖的状态机——通过两条路径达到相同最终状态会产生不同结果。
  4. 跨模块与跨链假设——一个合约假设了另一个合约未执行的属性。

这是造成 2025/2026 年单协议最大损失的类别,也是自动化扫描最少能捕捉到的类别,因为正确性是协议特定的。按美元金额计算,2026 年的智能合约漏洞越来越多地属于业务逻辑漏洞,SC02 的提升正是 OWASP 对这一事实的认可。

示例。

  • Yearn yETH(约 900 万美元,2025 年 11 月)。上一节已详细说明——定点求解器崩溃,将稳定币不变量转化为常数和。
  • Cetus(2.23 亿美元,2025 年 5 月)。库级别 u256 溢出检查未中止。上一节已详细说明。
  • Balancer V2 ComposableStablePool(约 1.2864 亿美元,2025 年 11 月 3 日)。据 Trail of Bits 归因:_upscaleArray 中的舍入错误漏洞与精心构造的 batchSwap 操作相结合,使攻击者能够人为抬高份额价格。这跨越了 SC02(业务逻辑)和 SC07(舍入)——这正是关键所在。复合故障很少局限于单一类别。
  • Abracadabra(约 1300 万美元,2025 年 3 月)。GMX 流动性代币大釜。攻击者利用了清算逻辑与底层 GLP 之间的交互。

值得记住的结构性先例是 Euler Finance(2023 年 3 月,约 1.97 亿美元)。donateToReserves 函数——被攻击者利用——最初是作为针对较小首次存款人通胀问题的补丁而引入的。这个打补丁后的函数缺乏健康检查。签署通过的审计方同时也是该协议的保险公司。那个故事就是 SC02 类事件的结构性模板:漏洞通过善意的修复方式进入;数学上局部正确;不变量全局性崩溃。

检测方法。

SC02 的审计响应是结构性的,按以下顺序进行:

  1. 首先进行威胁建模。 明确定义协议的不变量。对于借贷协议:Σ 用户余额 ≤ 总资产,在每条状态变更路径(包括 donate*migrate*rebalance*)之后 健康状况 ≥ 1。对于 AMM:x · y ≥ k(扣除费用后)。对于稳定币兑换池:在所有流动性比率下迭代求解器的边界。
  2. 不变量的模糊测试。 Foundry 有状态模糊测试、Echidna 或 Medusa 针对这些不变量运行随机化的调用序列。对于任何具有可组合状态的协议来说,这是不可商量的。
  3. 高价值属性的形式化验证。 Halmos 符号化证明所有有界输入下的不变量;Certora 的 CVL 涵盖协议级规则。
  4. 对抗性经济模拟。 基于代理的模型,假设无限资本的闪电贷、MEV 的 mempool 排序以及对抗性排序。

一个 ERC-4626 金库的初版属性文件可能如下所示:

1// foundry-rs/forge-std 不变量测试
2function invariant_solvency() public {
3    assertLe(vault.totalSupply() * vault.convertToAssets(1e18) / 1e18, vault.totalAssets());
4}
5
6function invariant_round_trip_loss() public {
7    uint256 shares = vault.convertToShares(amount);
8    uint256 assets = vault.convertToAssets(shares);
9    assertLe(assets, amount); // 对用户不利的方向取整
10}

四行代码。配合随机调用序列大规模运行,你就能在它们进入生产环境之前捕捉到相当一部分 SC02 发现。

Zealynx 覆盖。 覆盖充分,已有若干支柱文章发布:

SC03:2026 — 价格预言机操纵

定义。 任何智能合约依赖可由攻击者直接或间接影响的价格或估值数据的情况。预言机是信任边界;合约隐式信任其数据源。

示例。 sDOLA / Llamalend on Curve(约 24 万美元,2025 年)——流动性稀薄池上的单来源链上预言机,攻击者操纵了价格源并触发了人为清算。Makina(约 413 万美元,2026 年 1 月)——闪电贷资助的 DUSD/USDC Curve 池上的预言机倾斜。

检测方法。 尽可能验证多来源去中心化预言机(Chainlink 价格源、Pyth);对任何基于现货价格的预言机强制执行 ≥30 分钟的 TWAP 窗口;对 updatedAtansweredInRound 进行过期检查;执行合理性边界(minPrice/maxPrice);设计安全失效机制(在价格源过期时暂停)。必须对通过 Balancer 式 getReserves() 调用的只读重入进行建模——见 SC08。

1function getPrice() internal view returns (uint256) {
2    (, int256 answer,, uint256 updatedAt, uint80 answeredInRound) = feed.latestRoundData();
3    require(answer > 0, "负价格");
4    require(updatedAt + 过期阈值 >= block.timestamp, "过期的价格源");
5    require(answeredInRound > 0, "不完整的轮次");
6    require(uint256(answer) >= 最小价格 && uint256(answer) <= 最大价格, "超出范围");
7    return uint256(answer);
8}

这就是预言机读取应该有的样子。大多数预言机操纵发现都发生在这些检查中有两三个缺失时。

Zealynx 覆盖。 DeFi 中的移动平均线Uniswap V2 深度解析(涵盖 TWAP 构造)以及预言机操纵支柱文章

SC04:2026 — 闪电贷助长攻击

定义。 原子性的、无抵押的借款,会放大任何潜在的漏洞。2026 年排名上升 3 位反映了闪电贷放大现在已成为默认的攻击原语,而非一种非常规手段。

示例。 Makina(约 413 万美元,2026 年 1 月)是近期最清晰的案例——闪电贷资助了预言机倾斜。2023 年 Euler Finance 攻击仍然是审计讨论中的经典示例:3000 万美元 DAI 闪电贷 → 杠杆化的 eDAI/dDAI 头寸 → donateToReserves(无健康检查)→ 在动态平仓因子下自清算 → 提取约 1.97 亿美元。

复合攻击链:从闪电贷到资产提取

检测方法。 将每个外部入口点视为攻击者拥有无限的单个区块资本。使用多区块 TWAP 预言机。在存款和借款之间添加最低持有时间。添加操作后的健康检查。对于治理,使用多区块投票权重快照(Merkle 证明或 Snapshot 风格的链下方案),以便闪电贷获得的代币无法投票。

Zealynx 覆盖。 闪电贷词条涵盖了定义和防御模式;MEV 保护文章涵盖了全栈闪电贷和 MEV 防御。

SC05:2026 — 缺乏输入验证

定义。 OWASP 将此定义为智能合约处理外部数据(函数参数、calldata、跨链消息、签名负载)时,未强制数据格式正确、在预期范围内且已针对预期操作获得授权的情况。

示例。 YO Protocol(约 371 万美元,2026 年 1 月)——滑点参数接受时未进行边界检查,且部署配置中设置了宽松的默认值。Aave 5000 万美元滑点事件(2026 年 3 月)——UI 发出警告,合约未强制执行。

检测方法。 将前端视为不存在。每个外部输入都应有明确的 require 边界;每个地址参数都应有零地址检查,并在适用时进行代码大小/合约存在性检查;每个数值参数都有最小值和最大值;每个截止时间都有边界。calldata 长度验证必须在 abi.decode 之前进行。

1function swap(address tokenIn, uint256 amountIn, uint256 minAmountOut, uint256 deadline) external {
2    require(tokenIn != address(0), "代币地址为零");
3    require(amountIn > 0, "数量为零");
4    require(minAmountOut > 0, "最小输出为零"); // 关键——防止简单的夹子攻击
5    require(deadline >= block.timestamp, "截止时间已过");
6    require(deadline <= block.timestamp + 最大截止时间差, "截止时间太远");
7    // ...
8}

minAmountOut > 0 这一行正是 Aave 5000 万美元事件本可以在协议层面(无论 UI 如何)阻止的那一行。

Zealynx 覆盖。 间接覆盖——输入验证在 Solana 安全检查清单代理与可升级性检查清单中被提及,但未作为独立支柱文章。

SC06:2026 — 未检查的外部调用

定义。 与外部合约的不安全交互,其中失败、回滚或回调未得到安全处理。该类别涵盖了一个合约在未经验证的情况下信任另一个合约的广泛表面。

示例。 CrossCurve Bridge(300 万美元,2026 年 2 月)——Axelar 的 expressExecute 函数缺少访问控制,允许任何调用者调用快速执行路径并重定向跨链资金。该函数的存在是为了流动性提供者报销;但它对任何人都可访问。

检测方法。 每个低级 calldelegatecall 都要检查成功布尔值;每个 transfertransferFrom 都必须使用 SafeERC20(或其等效方案);强制执行 CEI;使用 try/catch 来覆盖可能回滚但不应中止上游逻辑的调用;永远不要信任 tx.origin。对于跨链桥,验证 chainId 和跨链消息的证明。

1// 错误
2token.transfer(recipient, amount);
3
4// 正确(OZ SafeERC20)
5token.safeTransfer(recipient, amount);
6
7// 错误
8(bool ok,) = target.call(data);
9
10// 正确
11(bool ok, bytes memory ret) = target.call(data);
12require(ok, _getRevertMsg(ret));

Zealynx 覆盖。 信任边界词条ERC-4337 六种故障模式文章以及跨链桥安全清单

SC07:2026 — 算术错误(舍入与精度)

定义。 2026 年新增的独立类别。智能合约受限于整数算术;除法、定点缩放以及单位之间的转换会损失精度、引入不对称舍入,或者——当与 unchecked 块或非 EVM 语义结合时——导致溢出和下溢(现在归类为 SC09)。

典型模式:ERC-4626 首次存款人通胀。攻击者铸造 1 wei 份额,直接向金库捐赠资产以抬高 totalAssets,受害者的存款随后被向下舍入到零份额。OpenZeppelin 的缓解措施是 _decimalsOffset 虚拟份额与资产模式。

示例。 Balancer V2 ComposableStablePool(约 1.2864 亿美元,2025 年 11 月 3 日)。Trail of Bits 将该事件归因于 _upscaleArray 中的舍入错误漏洞与精心构造的 batchSwap 操作相结合。孤立来看算术是正确的;但在组合操作中,舍入方向却不对。

检测方法。 对用户不利的方向取整——存款时向下取整,取款时向上取整。对于新的 ERC-4626 金库,使用虚拟偏移量。使用极端值(1 wei、type(uint256).max)进行模糊测试。形式化验证转换恒等式:

∀ x: convertToAssets(convertToShares(x)) ≤ x

这个属性,用 Halmos 的 check_* 形式或 Certora CVL 编写,在对一个干净实现进行证明时需要几分钟时间,是针对该类别的成本最低的保险。

Zealynx 覆盖。 Solidity 溢出与下溢文章通过真实的审计发现覆盖了底层机制;Balancer 架构文章讨论了 V1→V3 中的精度疲劳问题。

SC08:2026 — 重入攻击

定义。 在状态完全更新之前,外部调用重新进入易受攻击的函数。OWASP 在 2026 年列举了四种变体:单函数、跨函数、跨合约以及只读重入。只读重入是 2024 年后最被低估的变体——外部调用者在回调期间读取过时的 getReserves() 样式数据,即使没有状态变异重新进入。

示例。 Solv Protocol ERC-3525(270 万美元,2026 年)——带有转账回调的半同质化代币,在转账状态最终确定之前重新进入了铸造函数,导致重复头寸。

排名下降的原因。 成熟的防护措施。ReentrancyGuard 几乎普遍使用。CEI 已内化。Slither 和 Mythril 能可靠检测到经典模式。剩余表面是回调驱动的(ERC-721/1155/3525/777 Hook、ERC-4626 存款/取款Hook、闪电贷回调)以及只读重入。该类别排名下降,但并未消失,而且剩下的变体比大多数安全课程仍在教授的 2016 年 The DAO 原型更为微妙。

检测方法。 在每个改变状态的外部入口点使用 nonReentrant(或 nonReentrantTransient);各处都使用 CEI;对 ERC-777/1155/3525/4626 回调进行显式建模;对另一个协议作为预言机使用的每个视图函数进行只读重入审查。经验法则:如果你的 getReserves() 等效函数在交易中间可被调用,那么就要对在那个窗口中外部读取器会看到什么进行建模。

Zealynx 覆盖。 重入攻击支柱文章涵盖了现代变体;Uniswap V2 文章Balancer 架构文章在生产级代码库中涵盖了只读重入;分而治之方法论在信任边界层面解释了只读重入。

SC09:2026 — 整数溢出与下溢

定义。 Solidity 0.8+ 默认检查算术,并在溢出/下溢时回滚。剩余表面是 unchecked 块(用于 gas 优化)、内联汇编、自定义数学库以及具有不同溢出语义的非 EVM 平台——Move/Sui、Solana/Rust。

示例。

  • TrueBit(2620 万美元,2026 年 1 月)。0.8 之前的合约,getPurchasePrice 中未受保护的加法溢出到零,以零成本铸造了大量 TRU。2026 年的事件,代码库是 2018 年时代的。
  • Cetus(2.23 亿美元,2025 年 5 月)。Sui 的 u256 checked_shlw 左移在溢出时未中止。Move 对左移的设计选择,加上对高位检查存在缺陷的安全验证,产生了 SC07/SC09 混合漏洞。

检测方法。 必须使用 Solidity ≥0.8。每个 unchecked 块都附有不可能性的证明(一条注释显示防止溢出的边界)。对所有显式向下类型转换使用 SafeCast。在 Solana 上,仅使用 checked_addchecked_mul——对金融数值绝不使用原始 +*。对于 Move/Sui,明确审计移位操作和库数值代码。这正是 Cetus 案例中在三轮审计中明显覆盖不足的表面。

Zealynx 覆盖。 Solidity 溢出与下溢文章Solana 2026 安全概述以及45 项 Solana 安全检查清单

SC10:2026 — 代理与可升级性漏洞

定义。 OWASP 的完整描述:任何智能合约使用可升级架构(代理、信标或实现交换模式)且升级路径、初始化或管理控制设计不当或配置错误的情况。该类别分为四个子问题——本文前面已介绍。这是 OWASP 智能合约 Top 10 2026 中结构上最重要的新增类别,因为它将一个以前半属于 SC01、半属于 SC02 的故障表面剥离出来,并给予了 2025 年事件数据所证明的应有关注。

未初始化的 ERC1967 代理攻击流程

示例。

  • Kinto Protocol(155 万美元,2025 年 7 月)。攻击者检测到新部署但尚未初始化的 ERC1967 代理。他们自己调用 initialize,使用包含休眠后门的恶意实现。几个月后,后门被激活,代理被升级为恶意代码,K 代币被铸造以抽干 155 万美元。
  • 更广泛的未初始化代理运动(2025 年,累计超过 1000 万美元)。自动化扫描器监控多条 EVM 链上的新 ERC1967 代理,在合法部署者的交易提交之前抢先初始化它们,并嵌入能够在后续审计中存活的休眠后门。
  • FOOMCASH(226 万美元,2025 年)。面向 zkSNARK 验证器的可升级代理;配置错误的验证密钥允许伪造证明;升级机制缺乏时间锁和适当访问控制。

检测方法。 代理与可升级性发现存在于模式选择、初始化卫生、存储纪律和治理的交汇处。审计清单是结构性的:

  1. 模式选择。 在编写代码之前选择代理模式(Transparent、UUPS、Beacon、Diamond);使用 OpenZeppelin Upgrades 插件,而非定制的实现。定制代理是该类别中风险最高的子集。
  2. 初始化卫生。 正确应用 initializerreinitializer 修饰符。实现合约在构造函数中调用 _disableInitializers()。通过 ERC1967Proxy calldata 与代理部署原子化地执行初始化,以防止 Kinto 类别的竞态条件。
  3. 存储纪律。 通过 uint256[50] __gap 预留空白,或者更好的是使用 ERC-7201 命名空间存储。使用 OpenZeppelin Upgrades 插件验证不同版本的存储布局兼容性。UUPS 实现必须包含 proxiableUUID()(槽位 60894...)并覆盖带访问控制的 _authorizeUpgrade
  4. 升级治理。 时间锁 + 多签。链上公告。审查窗口。回滚能力。单一 EOA 升级权限自动构成严重发现。
  5. 特殊情况。 信标升级需要在信标上进行身份验证;共享的代理管理员和逻辑所有者密钥必须分离;实现上的 selfdestruct 暴露是致命的。

最小的正确实现模式:

1contract MyImplementation is UUPSUpgradeable, OwnableUpgradeable {
2    /// @custom:oz-upgrades-unsafe-allow constructor
3    constructor() {
4        _disableInitializers(); // 防止实现初始化
5    }
6
7    function initialize(address owner_) public initializer {
8        __Ownable_init(owner_);
9        __UUPSUpgradeable_init();
10    }
11
12    function _authorizeUpgrade(address newImpl) internal override onlyOwner {
13        require(newImpl != address(0), "实现地址为零");
14        require(newImpl.code.length > 0, "不是合约");
15    }
16}

三行代码(_disableInitializers()initializer 修饰符、_authorizeUpgrade 检查)就能防止 2025 年占主导地位的故障模式。但它们很少同时出现。

Zealynx 覆盖。 Zealynx 已经以不寻常的深度覆盖了这个类别:

如何实际根据 2026 年清单进行审计

针对 2026 年 OWASP 清单的审计响应框架

2026 年清单不是一个检查清单。它是一个优先级信号。跨越所有十个类别的审计响应具有共同的形态:

  1. 映射信任边界。 每个 external/public 函数、每个外部调用、每个跨合约依赖、每个链下输入。图表很有帮助。Zealynx 发布的分而治之方法论是我们内部使用的框架。
  2. 用通俗语言定义不变量。 对于任何非平凡协议,定义十个或更多的不变量。Σ 用户余额 ≤ 总资产健康状况 ≥ 1 在每条状态变更路径之后。convertToAssets(convertToShares(x)) ≤ x。偿付能力。守恒。可访问性。
  3. 将不变量转化为属性测试。 Foundry 有状态模糊测试、Echidna、Medusa 用于随机搜索。Halmos 和 Certora 用于需要证明而非搜索的高价值子集。
  4. 应用每个类别的工具。 对于 SC01/SC06/SC09,使用 Slither 和 Aderyn。对于 SC07 转换恒等式,使用 Halmos。对于 SC02 不变量崩溃,使用 Echidna。对于 SC10 存储布局检查,使用 OpenZeppelin Upgrades 插件。
  5. 对工具无法触及的部分进行手动审查。 业务逻辑正确性与协议意图的对比。链下信任假设。与范围外外部协议的可组合性。博弈论边缘案例。
  6. 部署后的持续验证。 相同的不变量作为链上监控器运行。相同的属性测试在每次提交时在 CI 中运行。相同的就绪检查在每次升级抢跑。

复合攻击模式——闪电贷 → 预言机倾斜 → 业务逻辑破坏 → 资产提取——是为什么这需要成为一个系统而非逐类别审查的原因。孤立来看每一步都能通过。组合起来就会失败。

对于刚起步的团队,我们的审计前技术清单涵盖了仓库卫生、不变量文档和静态分析分类,而审计 ROI 框架解释了如何在向审计师预订时间之前内部证明该项支出的合理性。


联系 Zealynx

在 Zealynx,我们按照 2025 年事件数据所要求的方式,根据 2026 年 OWASP 智能合约 Top 10 进行审计:结构性不变量测试、高价值属性的形式化验证、扩展到链下组件的信任边界映射,以及对抗性经济模拟。我们不仅撰写报告,还会编写属性测试。

如果你的协议持有用户资金,并且你还没有针对它运行过有状态不变量模糊测试,那么这就是你本季度能买到的最具成本效益的一小时安全投入。在升级上线之前与我们谈谈。

预约通话 —— 或者在联系我们之前,阅读我们如何在 2026 年为审计定价以及审计的实际成本


常见问题:OWASP 智能合约 Top 10 2026

  1. OWASP 是什么?为什么它会发布智能合约 Top 10? OWASP——开放全球应用安全项目——是一个非营利基金会,自 2003 年以来一直发布 Web 应用风险的权威“Top 10”清单。智能合约安全 (SCS) 项目是维护智能合约 Top 10 的 OWASP 工作组,该清单根据前一年的事件数据,以经验为基础对最具影响力的智能合约漏洞类别进行排名。2026 年清单锚定于 2025 年发生的 122 起独立事件,这些事件造成了约 9.05 亿美元的纯合约损失。它是智能合约行业用于优先安排安全工作方面最接近共享语言的东西。

  2. 什么是不变量测试?为什么 2026 年清单如此依赖它? 不变量是一个属性,它必须在协议的每个可达状态下都成立——例如“用户余额之和永远不会超过总资产”或“每次状态变更调用后,每个借款头寸的健康状况 ≥ 1”。不变量测试(也称为有状态模糊测试)运行随机化的合约调用序列,并断言这些属性在每一步之后都成立。像 Foundry 的不变量工具、Echidna 和 Medusa 这样的工具会自动执行此操作。2026 年清单强调不变量测试,是因为业务逻辑漏洞 (SC02)(2025 年金额损失最大的类别)正是那些能通过代码级别审查但在组合操作下破坏不变量的错误。我们的模糊测试与形式化验证文章是详细版本。

  3. 什么是“只读重入”?它和经典重入有什么不同? 经典重入利用的是合约在更新自身状态之前调用外部地址——外部地址重新进入函数并基于过时状态进行操作。只读重入则更微妙:攻击者触发一个回调,导致一个视图函数(通常是 getReserves()latestPrice() 或类似函数)返回暂时不一致的数据,而另一个第三方合约将该视图函数用作预言机,在回调窗口期间读取错误的值。原始合约的状态没有被破坏——但使用其视图函数的协议做出了错误的决定。Curve 和 Balancer V2 的只读重入模式在 2022-2023 年间造成了数千万美元的损失,并且该变体在 2025/2026 年仍在发生。

  4. 什么是 ERC1967 代理?为什么未初始化的代理会成为一种自动化攻击运动? ERC1967 是以太坊代理合约的标准:一个薄合约,将所有调用委托给一个单独的“实现”合约,该实现合约的地址存储在一个固定的存储槽中。代理使可升级成为可能——更换实现,代理地址保持不变,用户的状态和余额得以保留。攻击方式:如果部署者在一个交易中创建代理,在另一个交易中调用 initialize(设置所有者),那么监控每条 EVM 链上交易池的自动化机器人可以抢先调用 initialize,嵌入一个恶意的所有者或实现。Kinto Protocol(155 万美元,2025 年 7 月)是被引用最多的案例;该运动造成的总损失超过 1000 万美元。修复方法是将 initialize 作为代理部署 calldata 的一部分原子化地调用。我们的33 项代理与可升级性检查清单详细介绍了全部攻击和修复面。

  5. 什么是“复合利用”?为什么 2026 年清单强调组合而非单一类别错误? 复合利用是一种攻击,它串联跨不同 OWASP 类别的多个弱点,其中每一步孤立来看可能通过审查,但组合起来却破坏了一个不变量。2026 年的典型链条是:闪电贷提供对抗性资本 (SC04) → 预言机操纵扭曲价格参考 (SC03) → 业务逻辑缺陷允许抵押不足的操作 (SC02) → 未检查的外部调用或代理弱点完成资产提取 (SC06/SC10)。Euler Finance 攻击(1.97 亿美元,2023 年 3 月)和 Makina 漏洞利用(约 413 万美元,2026 年 1 月)是教科书式的复合利用。2026 年清单强调组合,是因为静态分析器、手动审查和逐类别检查清单都只操作孤立的代码片段——它们可能错过只有在三个片段交互时才存在的攻击。审计响应是不变量测试,它将系统作为一个整体进行建模。

  6. 2026 年清单将重入从第 2 位降至第 8 位——这是否意味着重入问题已经解决? 不是。该类别下降是因为常见的缓解措施——OpenZeppelin 的 ReentrancyGuard 修饰符、检查-生效-交互模式,以及坎昆升级后的 ReentrancyGuardTransient(将守卫的Gas成本降低了一个数量级)——现在在 Solidity 代码库中几乎普遍使用,并且像 Slither 和 Mythril 这样的工具能可靠检测到经典的单函数模式。在生产发现中仍然存在的是通过 ERC-721/1155/3525/777 Hook的回调驱动重入、ERC-4626 存款/取款Hook、闪电贷回调以及只读重入(见上方问题 3)。Solv Protocol ERC-3525 事件(270 万美元,2026 年)是典型的近期案例。因此:表面缩小了,但剩余的表面比大多数审计课程仍在教授的内容更为隐蔽。该类别之所以仍保持在前十,正是因为这些更微妙的变体仍然在发生。

词汇表

术语 定义
访问控制 限制哪些地址可以调用特权函数的安全机制。
闪电贷 在单个交易中借入并偿还的无抵押贷款。
重入攻击 在状态更新前外部调用重新进入合约的利用方式。
只读重入 视图函数在回调期间返回不一致数据的变体。
价格预言机操纵 操纵价格源以利用依赖于预言机的逻辑。
代理模式 使用 delegatecall 到实现的可升级合约架构。
信任边界 两个具有不同安全或信任假设的系统之间的边缘。
不变量测试 断言协议属性在调用序列中成立的有状态模糊测试。
OWASP 智能合约 Top 10 年度最具影响力的智能合约漏洞类别排名。

查看完整词汇表 →

  • 原文链接: zealynx.io/blogs/owasp-2...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
zealynx
zealynx
江湖只有他的大名,没有他的介绍。