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