12种智能合约漏洞及修复方案
随着智能合约在保护数字资产方面的应用日益增多,开发者面临着各种安全威胁。近期的高调攻击事件——包括Penpie损失2700万美元和Cetus被黑客攻击2.23亿美元——凸显了正确编码以防止漏洞的重要性。
智能合约安全基础
智能合约在满足特定事件、条件和逻辑时执行流程、交易和其他任务,具体取决于它们的编程方式。它们部署在区块链上,例如以太坊或其他分布式账本基础设施,在那里监听来自加密安全数据源(称为预言机)的事件和更新。
金融、医疗保健和保险等许多行业使用智能合约来控制大量有价值数据和资源的流动,例如转账、提供服务和解锁受保护内容。这自然使它们成为恶意行为者的有吸引力的目标。
在设计和开发智能合约时,安全必须是首要任务。一旦智能合约部署到区块链上,就很难或不可能进行修补;必须将其删除、重新创建和重新部署。此外,一旦智能合约在区块链上,任何人都可以访问其中的漏洞。
12种关键漏洞及修复方案
1. 重入攻击
重入攻击向量存在是因为Solidity智能合约是强制执行的:每行代码必须在下一行开始之前执行。这意味着当合约向另一个合约进行外部调用时,调用合约的执行将暂停,直到调用返回。这实际上让被调用合约临时控制了接下来发生的事情,创造了无限循环的可能性。
修复方案:当智能合约的代码逻辑存在缺陷时会出现此漏洞。开发人员需要仔细设计外部调用,并始终检查和更新合约状态,例如在满足发送资金的请求之前减少以太币余额。添加重入保护器可以通过锁定合约来防止同时执行多个函数。
实例:在2024年对Penpie去中心化金融协议的重入攻击中,攻击者窃取了价值2700万美元的以太币。
2. 预言机操纵和闪电贷攻击
智能合约使用预言机访问和使用区块链外部的数据。这使它们能够与链下系统(如股票市场)交互。不正确或被操纵的预言机数据可能会错误地触发智能合约的执行;这被称为预言机问题。
修复方案:使用去中心化预言机(如Chainlink或Tellor),甚至多个预言机,是确保合约接收准确数据的最简单方法。这样的预言机使攻击者干扰数据变得更加困难和昂贵。
实例:Abracadabra去中心化加密资产借贷平台遭遇闪电贷攻击,攻击者窃取了约1300万美元的以太币。
3. 不安全随机性
加密算法在生成密钥和为智能合约执行其他操作时依赖随机数源。密码学的一个基本原则是随机数必须不可预测,虽然这听起来很明显,但实现起来通常相当具有挑战性。
修复方案:仅使用基于公认标准的随机数生成加密技术。NIST有一个完整的研究项目和一套专注于随机数生成的标准。
实例:$FFIST加密货币代币遭受攻击,导致损失约11万美元。该攻击可追溯到可预测的随机性源。
4. 业务逻辑错误
业务逻辑错误是智能合约内部或智能合约之间设计错误的总称。设计错误导致合约的行为与预期行为不同。
修复方案:开发人员应彻底测试所有合约代码,包括所有业务逻辑组合,并验证观察到的行为在每种情况下都与预期行为完全匹配。
实例:SIR.trading DeFi协议在2025年3月遭遇逻辑缺陷攻击,导致约35.5万美元被盗。
5. 强制喂送攻击
强制喂送攻击利用了开发人员无法阻止智能合约接收以太币这一事实。这使得向任何合约转移以太币变得容易——强制喂送它——以改变其持有的以太币余额,从而操纵任何仅依赖预期余额进行内部核算的函数逻辑。
修复方案:不可能以这种方式阻止合约余额操纵。切勿使用合约余额作为函数内的检查或防护,因为实际的以太币余额可能高于合约内部代码预期的余额。
6. 缺乏输入验证
所有软件都需要验证输入;这是几十年来软件开发的核心原则。软件开发者假设所有输入都将如预期那样是危险的。
修复方案:开发人员应确保所有输入在使用前都经过仔细验证,确保完全符合预期。在合约中添加双重检查,以防意外输入以某种方式通过验证并被处理。
实例:Onyx DeFi协议因输入验证漏洞遭受攻击,面临380万美元的损失。
7. 拒绝服务
与任何在线服务一样,智能合约容易受到DoS攻击。通过超载服务(例如身份验证),攻击者可以阻止其他合约执行或生成意外的合约回滚。
修复方案:使这些攻击对攻击者来说代价高昂是阻止它们的最佳方式。时间锁谜题和燃料费只是增加攻击者成本的一些方法。确保仅向受信任的合约进行调用也降低了DoS攻击造成严重问题的可能性。
8. 整数下溢和溢出
当算术运算的结果落在固定大小值范围之外时,会发生整数下溢和溢出:对于整数类型uint8,范围是零到255。高于255的值会溢出并重置为零,而低于零的值会重置为255。
修复方案:自2020年底发布0.8.0版本以来,Solidity编译器不再允许可能导致整数下溢和溢出的代码。检查任何使用早期版本编译的涉及算术运算函数的合约,或使用库(如SafeMath)来检查下溢和溢出问题。
实例:2025年5月Cetus去中心化交易所黑客攻击,造成估计2.23亿美元的损失,原因是遗漏了代码溢出检查。
9. 访问控制漏洞
任何人都可以访问区块链。除非加密,否则切勿将机密或敏感信息保存到区块链。智能合约内的状态变量和函数也可能对其他智能合约可见和可访问,这使它们容易被误用或滥用。
修复方案:开发人员应始终遵循最小权限原则实施适当的访问控制,使用Solidity的状态变量和函数可见性说明符分配必要的最低可见性级别,且不超过此级别。
实例:KiloEx去中心化交易所因智能合约中缺乏访问控制而遭受约700万美元的损失。
10. 燃料困扰
要在以太坊区块链平台上执行交易或执行智能合约,用户必须支付燃料费。支付燃料费是为了激励验证者投入验证交易所需的资源。
修复方案:不存在防止燃料困扰的有效技术。开发人员应编写合约,使其设置要发送的燃料量,而不是由用户设置。然而,燃料成本的上升可能意味着交易失败。
11. 交易顺序依赖攻击(抢先交易)
智能合约从作为待处理交易提交到网络的那一刻起就是公开可见的。这使得区块的矿工可以选择具有最高燃料费的交易。
修复方案:这些攻击很难避免。一种选择是仅接受燃料价格低于预定阈值的交易。或者,使用提交和揭示方案,涉及用户首先提交解决方案哈希而不是明文解决方案,以便潜在抢先交易者为时已晚无法查看。
12. 时间戳依赖
执行智能合约的节点生成时间戳值。由于以太坊平台的分布式性质,几乎不可能保证每个节点上的时间都正确同步。
修复方案:为避免此漏洞,开发人员不应使用block.timestamp函数作为控制或逻辑检查,或作为随机性源。
保持智能合约无漏洞
为了使智能合约既智能又安全,开发团队必须从一开始就内置安全性,并严格测试其逻辑和代码执行。
合约代码在部署后很难修补。第一次就确保安全是必要的。始终遵循智能合约安全最佳实践。除非开发团队包括专门的智能合约安全专家,他们可以通过单元测试每个函数来审计智能合约代码的逻辑缺陷和其他漏洞,否则请使用专门从事智能合约的审计服务来识别任何安全问题。