首页 资讯 正文

AirSwap智能合约漏洞详解:用户资产可被攻击者恶意吃单?

PeckShield 2019年10月09日 10:05

2019年09月13日 AirSwap 团队公布了一个 AirSwap 智能合约中存在致命的漏洞,这一漏洞可以使得用户的资产在某些情况下被对手恶意吃单『偷盗』,PeckShield 安全人员独立分析了该漏洞,并与AirSwap团队沟通了细节和修复方案。

漏洞影响概述

PeckShield 安全人员深入分析 AirSwap 智能合约后发现,这一漏洞只对最近上线的 Wrapper 有影响,AirSwap 团队在发现该问题后第一时间下线当前合约,并将 AirSwap 网站回退到之前使用的合约,从合约上线到问题修复整个过程仅持续了 24小时,可见 AirSwap 团队对于合约安全的重视程度之高。

PeckShield 安全人员独立分析了漏洞细节,并与 AirSwap 团队沟通细节和修复的方案, 同时将该漏洞命名为ItchySwap”

PeckShield 在此提醒,由于这一漏洞可使用户的资产被攻击者恶意偷盗,受此次影响的账号一共有 18 个,其中有部分账号有数万至数十万美元的资产,这些账号需要尽快完成升级,或与 AirSwap 团队联系。

ItchySwap 漏洞详解

一、AirSwap 合约

在分析之前,为方便起见,我们先定义几个概念:

1. maker:出售资产的一方;

2. taker:购买资产的一方;

3. order: maker 与 taker 之间发生资产交割的订单;

4. Indexer: AirSwap 中的订单簿,汇聚了当前正在出售及需要购买的资产信息。

下图说明了maker、taker 和 Indexer 之间的交互流程:

AirSwap 是一个基于 Ethereum 的点对点去中心化交易所,它集成了 Swap Protocol ,在其中作为一个自动托管服务,允许交易的双方(即 maker 和 taker)在以太坊上安全地交易任何资产。与许多去中心化交易所不同,AirSwap 虽然没有对资金进行托管控制,但仍然有一个用于匹配目的的集中式订单簿,它实现了一个用于交易和订单匹配的完全对等模型。

特别值得一提的是,有一个名为 Indexer 的链下服务,可以聚合来自 maker 和 taker 的交易意图,然后为他们提供匹配的服务。特别是,一旦 taker 找到了合适的 maker,他们就会开始进行场外价格的谈判。一旦达成协议,订单将由 Taker 通过 Swap Protocol 在链上进行填充和资产交割。

在 AirSwap 智能合约中, taker 将订单上链及资产交割的过程在 AirSwap swap(Types.Order calldata _order) 函数之中,这一函数实现如下所示:

1)验证订单有效性

订单 order 参数有效性检查,这些信息均由 taker 上链的时候指定的,也意味着这些信息都可以由 taker 篡改,具体包含:

1. 订单还在有效期内;

2. 订单还没有被其它的 taker 吃单;

3. 订单还没有被取消;

4. 订单的 nonce 大于最小值;

5. 设置订单状态为 TAKEN 状态。

2)验证 taker 信息

确立有效的 taker,根据 order 中指定或者等同于合约的调用方 msg.sender。

3)验证 maker 信息

验证 maker 的有效性,这里的验证分为两种情况考虑:

1. 没有 maker 签名的订单:需要保证 msg.sender 有权限操作这个 maker 地址即可,即这笔 order 发起者有权限操作 maker 的资产;

2. order 中指定了 maker 的签名信息:验证签名的有效性。

4) 资产交割

如果上述的验证流程没有问题,那么直接执行 maker 和 taker 的资产交割。

二、Wrapper 合约

在上述的 AirSwap 合约中,用户通过 swap() 函数执行资产互换,这一流程非常清晰,没有问题。但是这一合约存在一点不完美的地方,用户只能通过 Token 进行资产互换,无法直接用 ETH 平台币参与其中。用户可以先把 ETH 转换成 WETH, 再用 WETH 参与互换,但无论如何,用户使用体验上多了一步。

为了降低用户使用体验上的摩擦,AirSwap 团队与 2019年09月12日 推出了 Wrapper 合约,其使用是自动将用户转入的 ETH 转换成 WETH 之后再参与资产互换的过程,其关键流程如下:

1. 验证 swap() 发起方与 taker 是相同的;

2. 如果用户发起 swap() 有携带了 ETH 资产,并且需要转换的 token 为 WETH, 那么就自动将 ETH 转换成 WETH;

3. 直接调用 AirSwap 合约的 swap() 操作。

考虑到一种特殊的场景,Alice 希望通过 Wrapper 合约执行 AirSwap 资产互换,这一过程需要先由 Alice 自行在 AirSwap 合约中授权 Wrapper 合约,以允许 Wrapper 合约可以执行各自的资产交割流程。

由于区块链的透明性,Eve 看到了 Alice 的授权操作,那么他就可以向 Wrapper 合约发起一笔恶意的订单,其包含的内容如下:

1. order 中的有效时间、nonce 为一个非常大的数值;

2. order 中的 maker 对应的账号为 Alice 的账号;

3. order 中的 taker 为空;

4. order 的 signature 为空。

将上述构造好的 order 代入AirSwap 的 swap() 函数,其中 1,2 两步的验证由于是 taker 控制的,不会有问题,我们重点看下第三步验证 maker 信息:

由于此时 AirSwap 合约是由 Wrapper 合约调用的,那么 msg.sender 即 Wrapper 合约的地址,前文讲到,Wrapper 合约是经过 Alice 授权可直接控制 Alice 的资产,此时虽然 Eve 没有权限操作 Alice 的资产,但此时可以通过 Wrapper 控制,也就间接地控制了 Alice 的资产。

安全规避

PeckShield 安全人员分析发现,截止至 2019年09月28日为止,共有 6 个账号执行了 revoke() 操作,以解除对 Wrapper 合约的授权,还有 12 个账号存在安全风险,这剩下的所有账号应当立即执行 revoke() 操作,或者将账号中的资产转移至未对 Wrapper 授权过的安全账号。

任何的代码在上线生产环境之前都应当得到充分的测试和验证,特别是承载着用户价值的 DEX 平台。在产品增加新特性之时,一定要考虑到旧特性的兼容性与安全,新特性的引入不应该触发旧产品中设计不完备的地方

附录

备注:AirSwap 官方漏洞细节(原文)链接:https://medium.com/fluidity/critical-vulnerability-in-a-new-airswap-smart-contract-c1204e04d7d3