2022 年 2 月 OpenSea 钓鱼事件复盘:一张零元订单如何顺走整排授权 图 1
2022 年 2 月 OpenSea 钓鱼事件复盘:一张零元订单如何顺走整排授权 · 图 1

2022 年 2 月 20 日,一批 OpenSea 用户发现自己没有做任何操作,NFT 却开始离家。安全公司 Check Point 当天发布复盘:受害者合计被转走价值约 170 万至 200 万美元的藏品,涉及二十多个钱包,攻击者随后陆续抛售。CertiK 后来把这次事件列为 2022 年 NFT 钓鱼案中收益第二高的一起。它之所以被反复引用,不是因为金额,而是因为攻击路径把三个各自正常的安全假设拼成了一个漏洞组合。

第一步是邮件。当时 OpenSea 正在推进合约迁移,官方渠道确实公告过用户需要把旧合约挂单迁移到新合约,Check Point 注意到攻击者用与官方几乎相同的邮件模板给受害者发送了内容相近的迁移指引。对收件人来说,这是一封时机、格式、措辞都挑不出毛病的信,唯一可疑之处要到点击之后才会暴露:仿冒站点弹出的是一笔需要签名的交易。

第二步是签名本身。多家机构的复盘还原了同一结构:受害者被诱导签下的是一笔金额为零以太币、看似无害的订单。关键在于 Wyvern 协议——当时 OpenSea 撮合引擎——的结算方式:订单由买卖双方签名加各自随单数据构成,合约校验的是签名与参数的一致性。受害者亲笔签了名,订单在协议眼里就是合法订单,哪怕里面装的是零元付款和一个陌生对手方。这一步的教训和钱包签名核对清单高度重合:人话版金额、收款方地址、订单类型,缺一项都不要落笔。

第三步,也是这次事件真正的独特之处:搬走的不止这笔订单涉及的资产。Halborn 与 CertiK 的复盘都指出,攻击订单的调用数据指向攻击者合约,执行时借助受害者此前对 OpenSea 相关通道留下的授权。许多用户曾把多个系列的 NFT 批准给交易所的代理合约,授权没有过期时间,撤销需要自己动手。攻击者用一笔合法签名的订单敲开代理合约后,循环调动这些存量授权,把受害者名下多个被批准系列的藏品逐批转走。换句话说,钓鱼签的是一扇门,真正搬东西用的是门后早已堆好的钥匙串。

把三层拆开,防御动作就变得很机械。第一层,验证消息来源:OpenSea 官方当时明确提醒以官方渠道发布的链接为准,社交平台私信与邮件都不是安全信道;涉及合约迁移这类基础设施变动时,宁可多花十分钟从官网入口重新找公告。第二层,把签名当转账读:零元不等于零风险,订单里的对手方地址、调用目标和过期时间都要看。第三层,定期清点授权:对代理合约与市场通道的 approve 不会自己到期,不挂单时撤销、换钱包时重查,是成本最低的止损位。此后 OpenSea 迁移到 Seaport 体系、市场普遍收紧默认授权模型,都是这次事件推动的行业修正。攻击者没有破解任何密码学假设,他只是让一个合法签名去触发一堆旧授权——这恰恰是 NFT 托管安全里最常被低估的一条:风险不在你签名那一刻的资产,而在你历史上留下的权限。

事件后的制度补丁同样构成复盘的一部分。OpenSea 在迁移完成前后持续强调以官方渠道为准的沟通纪律,行业则把撤销审批工具推向日常化:Etherscan 的 token approval 检查页、各钱包的权限管理面板,都在 2022 年之后成为 NFT 用户手册的标配。协议层的改动更根本:接任撮合核心的 Seaport 把授权对象收窄到更细的订单粒度,默认模型下挂单不再要求对整条转账通道长期开放权限,签名订单过期即失效的设计也让一张旧签名能撬动的资产面大幅缩小。回头看,这次事件被反复引用正因为它划出了一条清晰的分界线:账户安全从私钥保护一个维度,扩展成私钥、签名内容审查与存量授权清点三者并立的模型,此后 NFT 盗损案例的绝大多数路径,都能映射回这三层中的至少一层。

本文为机制说明,不构成任何投资建议。

2022 年 2 月 OpenSea 钓鱼事件复盘:一张零元订单如何顺走整排授权 图 2
2022 年 2 月 OpenSea 钓鱼事件复盘:一张零元订单如何顺走整排授权 · 图 2