返回博客

安全智能合约开发——NFT合约中的重入漏洞

Code Auditing
2022年8月5日
阅读约 4 分钟

引言

鉴于以太坊上 NFT 生态系统的繁荣以及相关安全问题的增加,我们将发布一系列博客文章,介绍这些安全问题,并为开发人员提供一些保护智能合约的建议。在本篇博客中,我们将介绍 NFT 合约 中的重入问题以及如何缓解相关的漏洞。

什么是重入

根据 维基百科

在计算中,一个计算机程序或子程序如果能够安全地在多个处理器上并发运行,或者在单处理器系统上,一个可重入过程可以在执行中途被中断,然后在之前的调用完成执行前被安全地再次调用(“重入”),则称该程序或子程序是可重入的。

在智能合约中,当一个函数执行另一个合约的外部调用,而该外部调用在原始函数返回之前进一步调用了原始函数(或其他函数)时,就可能发生重入。如果外部调用是由不受信任的实体(例如恶意合约)控制的,则可能导致意外结果。这是因为,在某些函数中,结果取决于合约状态。合约状态将在外部调用后更新。然而,该函数的重入调用将使用旧状态而不是更新后的状态。

重入一直是智能合约中普遍存在的问题,例如 MakerDAO 攻击,Uniswap 上的 ERC777,以及其他(请在 BlockSec Academy 上搜索 Reentrancy)。

NFT 中的重入

对于 NFT 合约,存在一些开发人员可能忽略的隐式外部函数调用。它们包括 onERC721Received 和 onERC1155Received 函数。onERC721Received 函数用于检查接收方合约是否能够处理 NFT(以防止 NFT 被永久锁定)。该函数在 ERC721 合约 的 safeTransferFrom 和 _safeMint 中被调用。 ERC1155 合约 中也存在类似的函数。由于这些外部函数调用,重入可能在未被合约开发人员注意到的情况下发生。

单函数重入

单函数重入是重入攻击的较简单形式。在这种类型的重入攻击中,被重入的函数与原始函数相同。攻击者可以在函数第一次调用完成之前反复调用该函数。在 NFT 合约中,这种情况通常发生在与 mint 操作相关的函数中。

例如,一些 NFT 项目可能允许每个用户免费铸造 NFT,设定整个项目的最大供应量,或者设定单个用户可以持有的 NFT 的最大数量。通常,这些限制是在实际铸造操作之前进行检查的。但如果与这些限制相关的状态是在 safeMint 函数之后更新的,攻击者就可以重入该铸造函数并绕过限制,因为相关状态与该函数的第一次调用是相同的。我们之前博客文章中发布的 HypeBears 重入攻击是一个例子。

一个更复杂的单函数重入发生在 safeMint 函数在循环中使用,并且限制在循环开始前检查。在这种情况下,即使在外部调用之前一些状态已经被自动更新,循环中剩余的 safeMint 函数调用仍然可以绕过验证,因为循环已经开始,而验证发生在循环开始之前。

例如,在另一篇 文章 中展示的示例中,mintNFT 函数会检查用户想要铸造的 NFT 数量加上当前供应量是否会超过最大供应量。safeMint 函数在 onERC721Received 外部调用之前更新总供应量。攻击者仍然可以利用这一点,因为 safeMint 函数每次只将总供应量增加 1。因此,如果攻击者在循环中第一次调用 safeMint 时重入 mintNFT 函数,总供应量将变为旧供应量加 1,而不是旧供应量加上 mintNFT 第一次调用将要铸造的 NFT 数量。

跨函数重入

攻击者不是进入相同的函数,而是可以进入与原始函数共享或依赖于状态的另一个函数。我们在之前的博客文章中详细介绍了一些案例,例如 Revest 案例 和 OMNI 案例。

总结和建议

以下是一些为 NFT 智能合约开发者提供的建议,以缓解重入威胁。

  1. 在代码中 使用检查-效果-交互模式。
  2. 在使用任何会引入外部调用的第三方库时要小心。对于 NFT 合约,要警惕 onERC721Received 和 onERC1155Received 函数的隐式回调。

阅读本系列的其他文章

关于 BlockSec

BlockSec 是一家开创性的区块链安全公司,成立于 2021 年,由一群在全球享有盛誉的安全专家组成。公司致力于提高新兴 Web3 世界的安全性和可用性,以促进其大规模采用。为此,BlockSec 提供智能合约和 EVM 链 安全审计 服务,用于安全开发和主动阻止威胁的 Phalcon 平台,用于资金追踪和调查的 MetaSleuth 平台,以及供 Web3 构建者在加密世界高效冲浪的 MetaSuites 扩展。

截至目前,公司已为 MetaMask、Uniswap Foundation、Compound、Forta 和 PancakeSwap 等 300 多家尊贵客户提供服务,并获得了 Matrix Partners、Vitalbridge Capital 和 Fenbushi Capital 等知名投资者两轮融资,总计数千万美元。

官方网站:https://blocksec.com/

官方 Twitter 账号:https://twitter.com/BlockSecTeam

订阅最新动态
Autheo Network、UNCX 遭黑客攻击,损失约387万 USD | BlockSec 周报
Security Insights

Autheo Network、UNCX 遭黑客攻击,损失约387万 USD | BlockSec 周报

本周报告涵盖 2026年10月12日–2026年10月18日 期间的 3 起安全事件,估计总损失约为 387万 USD。Autheo Network 因私钥泄露损失约 176万 USD,Qubic Wallet 因种子生成机制薄弱损失约 130万 USD;UNCX Network 在 Ethereum、BNB Chain、Base 和 Robinhood Chain 上的 Smart Token Vesting V2 合约因会计核算错误损失约 80.7万 USD。重点分析的 UNCX 事件说明,有缺陷的总份额计算将按不同代币与份额兑换比率创建的归属批次混合计算,从而使人能够从共享资金池超额提取。

损失约54.2万美元:MakerDaoBot 漏洞利用事件|BlockSec 周报
Security Insights

损失约54.2万美元:MakerDaoBot 漏洞利用事件|BlockSec 周报

本报告涵盖2026/10/05至2026/10/11以太坊上的1起安全事件,估计损失约54.2万美元。攻击合约部署恶意适配器,并将其传入缺乏访问控制的MakerDaoBot函数,使机器人授予该适配器操作其内部MakerDAO余额的权限。适配器结算了4笔旧版ETH-A拍卖,将200单位ETH-A抵押品兑换为WETH;攻击合约随后将其解包,并向攻击者转出200 ETH。

损失约4.18亿美元:Bitget、NEAR Intents遭利用攻击 | BlockSec Weekly
Security Insights

损失约4.18亿美元:Bitget、NEAR Intents遭利用攻击 | BlockSec Weekly

本双周安全报告记录了2026年9月21日至10月4日期间发生的八起事件,涉及以太坊、BNB Chain、Solana、比特币、波场、XRP Ledger、Zcash、Avalanche、NEAR等网络,损失约4.184亿美元。详细分析涵盖Bitget因第三方安全产品漏洞损失3.875亿美元,以及NEAR Intents因退款验证缺陷和状态回滚缺失损失387万美元。

Web3 最佳安全审计方

在上线之前验证设计、代码与业务逻辑,对标业内最高安全标准。

BlockSec 审计