本文分析了一种称为“零转账攻击”的网络钓鱼技术,攻击者利用用户依赖交易历史记录的习惯,通过零转账交易在用户的钱包交易历史中植入与受信任地址相似的攻击者地址,诱导用户误将资金发送到该地址。文章探讨了ERC-20标准的实现中存在的这一安全问题,并提出了潜在的解决方案,包括修改合约代码和改进用户体验模式。
作者:Vlad Estoup & Sebastian Fabry 安全性是协议层固有的,并且许多黑客攻击和攻击媒介通过安全设计最佳实践、经过审计和实战验证的代码以及一致的测试来主动预防。然而,网络钓鱼攻击并非来自在代码中寻找漏洞,而是通过操纵用户的行为。那么,Web3 开发者如何帮助用户免受此类攻击呢?
让我们深入研究一种称为“零转账攻击”的特定类型的网络钓鱼攻击。这是一种网络钓鱼技术,攻击者诱骗用户错误地将资金发送到攻击者的地址,因为它类似于用户交易历史记录中的受信任地址。根据 Coinbase 的说法,这种方法导致 2022 年 11 月下旬至 2023 年 2 月期间,来自各种钱包提供商的受害者资金损失了 1900 万美元,这只是冰山一角,因为很难区分有意交易和无意交易。
这项研究旨在强调 ERC-20 代币标准实现中的一种行为,该行为最近通过地址污染攻击在野外被利用。发布此内容的动机有两个:
任何帐户都有可能进行将零个代币转账到另一个帐户的交易。此交易将在区块链上执行和记录。攻击者会试图通过零转账来利用用户依赖交易历史记录并通过比较前几个和后几个字符来快速验证钱包地址的倾向。通过污染用户钱包的交易历史记录,攻击者能够利用那些快速复制/粘贴地址并进行频繁交易的人。
这种网络钓鱼攻击例证了没有“直接”安全影响的行为如何仍然导致巨大的经济后果。攻击者将通过以下三个步骤来利用这一点:
ERC-20 标准定义了一组规则和指南,用于在以太坊区块链上实现代币合约。ERC-20 代币合约的核心功能之一是 transferFrom 函数,它允许第三方代表代币所有者将代币从一个地址转移到另一个地址。它需要代币所有者的批准,通常通过调用 approve 函数来设置,该函数设置消费者的津贴。该函数可以被认为是 ERC-20 DeFi 生态系统的支柱。
直接引用ERC-20 标准关于 transferFrom 函数的内容:
除非 _from 帐户通过某种机制故意授权消息的发送者,否则该函数应抛出。
0 值的转移必须被视为正常转移并触发 Transfer 事件。
OpenZeppelin 的实现尽最大努力遵守这些声明。OpenZeppelin 的 ERC-20 中允许零值转移,但由于从技术上讲,任何地址对于任何代币都具有 0 的默认津贴,因此它们可以从任何地址执行到任何地址。
原因在于 _spendAllowance 函数如何评估调用者和资金发送者之间的批准。有一个 require 语句评估 currentAllowance 与发送者请求的金额,如果津贴不足以进行转移,它将返回“ERC20: insufficient allowance”。

话虽如此,规范中 must 和 should 之间存在明显的区别。虽然 ERC-20 标准规定,除非 _from 帐户通过某种机制故意授权消息的发送者,否则该函数应抛出,但在零值转移的情况下,该实现不会抛出,因为 currentAllowance 将为零,因此等于金额。实现的这一方面突出了 should 和 must 之间的细微差别,因为 must 语句得到严格遵守,而 should语句没有被解释为具有限制性。
对于任何选择的 from 和 to 地址,使用值为 0 执行 transferFrom 将会成功,即使 from 地址(资金发送者)和 address(this)(transferFrom 函数的调用者) 之间的批准已被明确设置为 0(未批准)。此行为适用于大多数 ERC-20 合约(Uniswap、Compound Finance、Solmate 和许多其他的行为方式相同),这意味着几乎没有保障措施来防止零值交易。
这允许攻击者使用 0 的金额从任意地址执行 transferFrom 指令。这些交易会触发 Transfer 事件,与其他任何转移一样。在这种情况下,它将包括受害者的地址、攻击者的地址和 0 值。如果链下客户端恰好正在监听此事件(对于钱包或任何跟踪交易数据的应用程序来说通常如此),它们将被此恶意数据污染。这导致了上面说明的潜在攻击媒介。
一些研究人员提出了一种链上解决方案来解决 ERC-20 标准地址污染攻击。拟议的解决方案包括修改 _spendAllowance 函数中的 require 检查,以评估 currentAllowance 是否大于或等于 amount 和 1 的最大值,这将要求 Approval 为非零。

这种方法将迅速解决地址污染攻击的问题,这些攻击最近变得越来越普遍。但是,此实现偏离了“0 值的转移必须被视为正常转移并触发转移事件”的声明。如果进行此更改,则 0 的 currentAllowance 将不满足此检查。
重要的是要了解 ERC-20 是最终的,无法更新,即使可以更新,也不会影响区块链上许多不可升级合约的行为。
当前的问题不在于触发事件本身,而在于链下工具如何显示这些事件以及用户如何依赖这些信息。与其试图改变一项长期存在的标准,不如通过默认不显示或不与零值转移进行交互,除非激活切换,从而对工具(例如,区块浏览器、钱包、交易所)进行更改可能更有效。
OpenZeppelin 最终对其实现中的零值交易进行禁止或限制的任何更改都可能会严重影响其当前用例,甚至可能会破坏许多用例。限制此实现可能会导致的问题多于它将为社区带来的好处。
我们诚邀就如何改进 ERC-20 实现提出建议,以更好地保护用户免受地址污染,同时遵守 ERC-20 且不影响庞大的 DeFi 生态系统。
目前解决此问题的主要方法是通过持续的教育和更安全的 UX 模式。通过在转移代币期间验证地址,而不是依赖钱包的内置机制来自动粘贴到字段中的地址,用户可以领先于利用“0 转移”的恶意行为者一步。
至于客户端如何监听这些事件,当 _value 为零时,监控 Transfer 事件并以不同的方式处理这些链下事件是有意义的,例如通过发出通知或避免使用数据来预先填充将来的地址字段。作为额外的安全层,唯一且鲜明地标识每个帐户的基于区块链的地址簿可以防止意外转移到不需要的地址。
实施这些指南可以帮助提高 Web3 用户的安全性。正如已经表明的那样,最终用户的安全性不仅取决于合约标准的安全实施,还取决于应用程序和钱包的 UX 模式。
OpenZeppelin 为区块链开发人员构建了最受信任的开源库:Contracts version 4.8。存储库经过测试、安全、优化和Gas效率,供 Web3 开发人员构建和部署 dApp、DeFi 和 Web3 项目。
共享这些考虑因素是为了继续努力改进整个区块链开发人员生态系统的安全最佳实践。对于安全咨询、智能合约设计、审计和事件响应 - 与 OpenZeppelin 安全团队联系。
- 原文链接: openzeppelin.com/news/ho...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!