Cointime

扫码下载App
iOS & Android

慢雾:Sui - Move 合约审计入门

Sui 作为一个新兴的高性能区块链平台,具备多项创新技术和独特性,同时专注于为各种应用场景提供快速、安全的交易体验。关于 Sui 的基础知识可查阅探索 Sui:高性能背后的技术与合约安全。与其他区块链常用的编程语言(如 Solidity)有所不同,Sui 使用 Move 语言,在一定程度上能解决 Solidity 高发的漏洞问题,如重入攻击、整数溢出、双花、DoS 攻击和编译器问题,但避免不了开发者在代码中引入错误。因此,开发者在使用时需要了解并注意一些独特的功能或特性,确保智能合约的安全性。

慢雾安全团队整合吸收了 Sui 社区分享的安全开发实践,并结合自身多年积累的安全审计经验,发布 Sui - Move 合约审计入门,旨在帮助开发者更好地理解 Sui 智能合约的安全风险,并提供实用的解决方案,以降低潜在的安全威胁。

由于篇幅限制,本文仅罗列 Sui - Move 合约审计入门的部分内容,欢迎大家在 GitHub 上 Watch、Fork 及 Star:https://github.com/slowmist/Sui-MOVE-Smart-Contract-Auditing-Primer/blob/main/README_CN.md。

1. 模块声明和可见性

1.1 "public(friend)" 函数(在最新的 Sui 版本中 "public(friend)" 被替换成 "public(package)")

定义:用于声明函数,使其只能被指定的友元模块访问。这提供了更细粒度的访问控制,介于 "public" 和 "private" 之间。

示例:

 1.2 "entry" 函数

定义:"entry" 函数是模块的入口点,允许从事务块中直接调用。参数必须来自事务块的输入,不能是块中先前事务的结果或被修改的数据。此外,"entry" 函数只能返回具有 "drop" 能力的类型。

示例:

 1.3 "public" 函数

定义:"public" 函数可以从事务块和其他模块调用,适合外部交互。在参数和返回值上没有和 "entry" 函数一样的限制,通常用于将功能暴露给外部。

示例:

2. 对象管理

2.1 对象的唯一性

定义:每个 Sui 对象都有唯一的 "objID",确保了对象在链上的唯一性。

2.2 包装和解包

定义:

  • 直接包装:将一个 Sui 对象作为另一个对象的字段,解包时必须销毁包装对象。
  • 对象包装:包装后的对象成为另一对象的一部分,不再独立存在。解包后对象的 ID 不变。

2.3 自定义转移策略

定义:使用 "sui::transfer::transfer" 定义自定义转移策略,针对具有 "store" 能力的对象,可以通过 "sui::transfer::public_transfer" 创建。

2.4 对象的属性

定义:Sui 对象的属性包括 "copy", "drop", "store", 和 "key",这些属性决定了对象的行为方式。

2.5 对象的权限检查

  • Address-Owned Objects

定义:由特定地址(账户地址或对象 ID)拥有的对象,只有对象的所有者可以访问和操作这些对象。

  • Immutable Objects

定义:不可变对象无法被修改或转移,任何人都可以访问。适用于需要全局访问但不需要修改的数据。

  • Shared Objects

定义:共享对象可以被多个用户访问和操作,适用于去中心化应用等场景,但由于需要共识,操作成本较高。

  • Wrapped Objects

定义:包装对象是将一个对象嵌入另一个对象,包装后的对象不再独立存在,必须通过包装对象访问。

3. 安全性检查

3.1 数值溢出检查

Sui 的智能合约默认进行数值溢出检查。

3.2 重入检查

所谓的重入攻击是在一笔正常的合约调用交易中,被插入一笔非预期的(外部)调用,从而改变整体的业务调用流程,实现非法获利的行为。涉及到外部合约调用的位置,都可能存在潜在的重入风险。目前的重入问题我们可以分为三类:单函数重入、跨函数重入以及跨合约重入。Move 语言的一些特性为防范重入攻击提供了天然的保护:

  • Move 中无动态调用,其外部调用都需先通过 use 进行导入,即外部调用都是预期、确定的。
  • 无 Native 代币转账触发 Fallback 功能。
  • 在 Move 中,资源模型确保资源一次只能由单个执行上下文访问。这意味着如果函数执行未完成,则在执行完成之前其他函数无法访问同一资源。

1. 溢出审计

说明:Move 进行数学运算时会进行溢出检查,运算溢出的话交易将失败。但需要注意的是,对于位运算,Move 并不会进行溢出检查。

定位:寻找代码中进行位运算的位置,检查是否有溢出风险。

2. 算术精度误差审计

说明:Move 中没有浮点类型。因此,在进行算术运算时,如果运算结果需要以浮点数表示,可能会产生精度误差。虽然精度误差在某些情况下难以完全避免,但可以通过优化和合理设计来减轻其影响。

定位:审查代码中所有涉及算术运算的部分,特别是可能产生精度误差的计算,确保这些运算不会对合约逻辑或数值准确性产生负面影响,并提出优化建议以减轻精度误差。

3. 条件竞争审计

说明:Sui 中的验证者也可以对用户提交的交易进行排序,因此在审计中我们仍需要注意在同一个区块中对交易进行排序而获利的问题。

定位:

  • 是否有对函数调用前合约的数据状态进行预期管理。
  • 是否有对函数执行中的合约数据状态进行预期管理。
  • 是否有对函数调用后的合约数据状态进行预期的管理。

4. 访问控制审计

说明:合约中的某些关键函数应仅限于内部调用,例如能够直接更新用户存款数额的函数。如果这些函数不慎对外部开放,可能绕过权限控制,导致安全漏洞,甚至引发资产损失。因此,必须严格设置访问权限,确保只有授权角色或模块可以调用这些函数,或者确保函数只能在内部使用。

定位:需要检查所有函数的访问控制设置,特别是那些不应该对外公开的函数,确保它们只能在内部调用。如果发现不应暴露的函数接口已经公开,必须标记为高风险并提出修正建议。

5. 对象管理审计

说明:在 Sui 中,对象可以被转换为共享对象 (Shared Object),这意味着对象的访问权限可能从私有变为公共。因此,需要对所有使用的对象进行详细审查,明确每个对象是静态的还是共享的。特别要注意是否有对象被错误地从私有对象转换为共享对象,这样可能导致未经授权的用户访问这些对象,带来潜在的安全风险。

定位:整理并分析模块中所有涉及的对象,检查对象的类型和权限设置,确保该对象的权限与业务需求匹配。如果发现私有对象被错误地转换为共享对象,必须标记为潜在风险并提出修正建议。

6. Token 消耗审计

说明:Sui 的代币模型与其他链的代币模型有所不同。Sui 允许对象持有代币,并且代币对象可以嵌套在其他对象中,还可以进行拆分。因此,在涉及代币消耗的场景中,需要特别关注代币的管理和流转,以避免安全问题或意外损失。

定位:

  • 检查消耗的金额是否准确。
  • 检查代币对象是否已经正确转移。
  • 检查代币的拆分和合并是否合理。
  • 检查代币与对象的绑定。

7. 闪电贷攻击审计

说明:Sui 的 Move 也有闪电贷的用法(Hot Potato)。用户可以在一笔交易中借取大量的资金任意使用,只需在这笔交易内归还资金即可。恶意用户通常使用闪电贷放大自身的资金规模进行价格操控等大资金攻击。

定位:分析协议本身的算法(奖励、利率等)及预言机依赖是否合理。

8. 权限漏洞审计

说明:在 Sui 的 Move 合约中,权限漏洞这部分和业务的需求以及功能设计关系较大,所以遇见较为复杂的 Module 时,需要和项目方确认各个方法的调用权限(这里的权限一般是指函数的可见性和函数的调用权限)。

定位:

  • 检查和确认所有函数方法的可见性及调用权限,在项目评估阶段就需要项目方提供设计文档,审计时根据设计文档中的描述从而确认权限。
  • 梳理项目方角色的权限范围,如果项目方角色的权限会影响用户的资产,则存在权限过大的风险。
  • 分析对外函数里面传递进去的对象是什么类型,如果是一些特权函数,则必须要有一些特权对象参与。

9. 合约升级的安全审计

说明:在 Move 中,外部模块通过 use 关键字导入。需要注意的是,Sui 的合约是可升级的,但发布的合约包(package) 是不可变的对象,一旦发布就无法撤回或修改。合约升级的本质是通过在新的地址上重新发布更新的合约,并将旧版本合约的数据迁移至新的合约中。因此,合约升级过程中需要特别注意:

  • "init" 函数:"init" 函数仅在合约第一次发布时执行,后续合约升级时不会再次触发。
  • 升级合约不会自动更新依赖:如果合约包依赖于外部包,当外部包升级时,合约包不会自动指向升级后的合约地址。因此,需要手动升级自己的合约包以指定新的依赖项。

定位:需要对合约升级过程中数据迁移的逻辑进行详细检查,确保迁移操作安全、准确,并避免遗漏重要数据或依赖更新的问题。

10. 外部调用安全审计

说明:与外部模块使用审计项相同,由于 Move 中进行外部调用需要先将外部模块导入,因此理论上外部调用的结果都是开发人员所预期,所需主要的是外部模块的稳定性。

定位:需要对外部引入的库进行检查。

11. 返回值的检查

说明:和其他智能合约语言类似,在 Move 合约中,需要对某些函数的返回值进行检查。如果忽略了对这些返回值的处理,可能会导致关键逻辑没有正确执行,进而引发安全问题。

定位:需要检查代码中每个函数调用的返回值,特别是那些涉及外部调用或重要状态更新的函数。如果返回值未被处理或验证,可能会导致不可预期的行为,应该标注为潜在风险点。

12. 拒绝服务审计

说明:拒绝服务(DoS) 攻击可能由代码逻辑错误、兼容性问题或其他安全漏洞引发,导致智能合约无法正常运行。此类问题可能影响合约的可用性,甚至使其完全瘫痪。

定位:

  • 重点检查业务逻辑的健壮性,确保在各种情况下都能正常执行,不会因错误或漏洞导致合约中断。
  • 关注与外部模块交互的部分,确保其兼容性,以防止由于外部依赖问题导致的服务中断。

13. Gas 优化审计

说明:与以太坊一样,Sui 也有 Gas 机制,任何模块脚本调用都会消耗 Gas。因此对一些冗长且高复杂度的代码进行优化是有必要的。

定位:

  • 涉及到复杂的调用看是否可以解耦。
  • 涉及到高频率的调用看是否可以优化函数内部执行的效率。

14. 设计逻辑审计

说明:设计逻辑审计的重点是检查代码中的业务流程和实现,确认是否存在设计缺陷或与预期不符的情况。代码实现如果与预期逻辑不一致,可能会导致意外的行为或安全风险。

定位:

  • 根据不同角色的权限和作用范围,梳理业务流程中的可能调用路径。
  • 确定每个业务流程所涉及的数据范围,确保数据的操作与业务设计一致。
  • 将实际的调用路径与预期的业务流程进行比较,识别并分析任何可能导致非预期结果的调用情况。

15. 其他

未在上述表述中体现的内容。

对开发者而言,遵循这些最佳实践,可以有效提升智能合约的安全性,减少潜在的安全风险。希望这一最佳实践可以帮助更多的开发者打造安全可靠的智能合约,推动区块链技术的健康发展。

参考:

[1] https://intro.sui-book.com/

[2] https://docs.sui.io/

[3] https://move-dao.github.io/move-book-zh/introduction.html

作者 | Victory!

编辑 | Lisa, Liz

评论

所有评论

推荐阅读

  • 法官再次驳回马斯克高额薪酬计划 特斯拉:上诉

    美国特拉华州法官再次驳回马斯克在特斯拉的高额薪酬计划,特斯拉官方社交媒体对此回应称,法院的判决是错误的,我们要上诉。这一裁决如果没有被推翻,就意味着是法官和原告律师在管理特拉华州的公司,而非它们的合法所有者——股东。

  • OpenAI回应被马斯克起诉:申请重复且依然毫无根据

    近日马斯克要求美国一法院阻止美国开放人工智能研究中心 OpenAI 非法转型为营利性企业。OpenAI 的一位发言人表示,马斯克的申请重复,且依然毫无根据。 今年 2 月,马斯克提起诉讼,称其在为 OpenAI 的创立提供资金等支持时,与该公司两名联合创始人曾有协议,OpenAI 应为非营利组织,但 OpenAI 违背了创始目标和使命,转而追求利润。6 月,马斯克撤回这一诉讼,8 月份又重新起诉。今年 11 月,马斯克对 OpenAI 提起的诉讼再度升级,指控 OpenAI 试图垄断生成式人工智能市场。

  • 国际刑警组织:警惕一种涉及稳定币的新兴加密货币欺诈行为

    国际刑警组织金融犯罪行动创纪录逮捕 5,500 人,缴获价值超过 4 亿美元的赃物。在行动期间发布了紫色通告,国际刑警组织警告各国警惕一种涉及稳定币的新兴加密货币欺诈行为。成员国被告知“USDT 代币批准骗局”,该骗局允许欺诈者访问和控制受害者的加密货币钱包。该两步方法首先使用浪漫诱饵技术引诱受害者,指示他们通过合法平台购买流行的 Tether 稳定币(USDT 代币)。一旦骗子赢得了受害者的信任,就会向受害者提供钓鱼链接,声称允许他们设置投资账户。实际上,通过点击,他们授权骗子完全访问,然后他们可以在受害者不知情的情况下将资金从钱包中转出。

  • 马斯克称SpaceX市值可能突破万亿美元

    有网友在社交媒体平台X发帖称,世界上有9家市值超万亿美元的公司,其中8家是美国公司。 对此,马斯克回复称,SpaceX有一天可能会成为它们中的一员。

  • 韩国再次推迟征收加密货币税,至2027年

    在今日的新闻发布会上,韩国最大在野党共同民主党(Democratic Party of Korea)院内领袖朴赞大(Park Chan-dae)宣布,放弃在 2025 年实施加密货币利得税的计划,同意再推迟两年至 2027 年。“推迟加密货币利得税”的提案由韩国政府和执政党国民力量党(People Power Party)提出,共同民主党此前称,推迟征税是执政党的政治伎俩。 最初,韩国计划对加密货币收益征收 20% 税款(22% 为地方税),原定于 2022 年 1 月 1 日生效。由于投资者和行业的强烈反对,该计划已两次推迟至 2025 年 1 月 1 日。今日新闻发布会后,将该税征收再次推迟至 2027 年。执政党国民力量党(People Power Party)还提出,“加密利得税宽限期 2 年仍不足够,应当放宽至 2028 年征收,对加密货币快速征税不可取,投资者可能会因此离开市场。国民力量党希望将实施时间推迟到 2028 年,以兑现在选举期间的承诺。”

  • 社区反馈链上AI代理Spectral交互合约遭黑客攻击

    12月1日消息,据 X 用户@RuslanMoody 发文提醒:“请勿与链上 AI 代理 Spectral 网站交互,其交互合约已遭黑客攻击。注:这不适用于流动性已在 Uniswap 上锁定的代币。” 另据 X 用户@0xYong_W 表示,Spectral 内盘已被别人“掏池子”。

  • 日本金融厅建议放宽信托银行发行稳定币的准备金要求,并实施旅行规则

    日本金融厅(FSA)近日向金融系统委员会支付服务工作组提出了一些有关加密货币和稳定币的想法,其中提到不愿允许信托银行以外的银行发行稳定币。而对于信托银行发行的稳定币,金融厅希望放宽目前要求所有资产必须以银行活期存款形式持有的准备金要求。但是,金融厅还希望实施旅行规则,要求信托银行发行的稳定币转账必须进行 KYC。 日本于 2022 年通过了稳定币立法,支持银行、持牌汇款公司和信托公司发行稳定币。作为其工作组演示的一部分,金融厅区分了在许可区块链上发行的稳定币和在公共区块链上发行的稳定币。它对这三种稳定币都存在于许可链上感到满意,但对允许持牌存款机构在非许可链上发行稳定币持谨慎态度。

  • 安全机构:Clipper遭攻击损失超50万美元,650万美元资金存在风险

    安全机构 fuzzland 联合创始人shoucccc 于 X 发文表示:“DEX Clipper 因 API 漏洞(如私钥泄露)遭到黑客攻击。目前损失超过 50 万美元,650 万美元资金面临风险,请用户立即提款。”

  • 日本金融厅提议为非交易所加密中介机构制定轻量级立法

    日本正在考虑为非加密货币交易所的加密货币中介机构制定新的轻量级立法。近期,日本金融厅(FSA)向金融系统委员会支付服务工作组提出了自己的想法。 日本于 2017 年为加密资产交易服务提供商(CAESP)引入了立法,涵盖了加密货币的买卖、充当经纪人、管理与这些服务相关的资金或提供托管。然而,许多不经营加密货币交易所的所谓 introducer 并不认为自身是 CAESP。 因此,金融厅正在考虑要求他们注册为中介的提案。introducer 有义务向用户提供信息,将受到广告限制,如果出现问题,可能会承担损害赔偿责任。 金融厅还考虑了如何处理损害赔偿。当前对不属于较大集团的其他金融服务中介机构的规定要求提供保证金以支付潜在损害赔偿。如果中介机构隶属于加密货币交易所,则损害赔偿可能由交易所承担。

  • 欧盟报告认可无需许可区块链在传统金融中的潜力

    欧盟近日发布了一份报告,探讨了传统金融(TradFi)中无需许可区块链的潜力。报告认为,无需许可的区块链至少应被视为传统金融和金融市场基础设施的选择,但需谨慎采用。 报告认为,此类区块链可以比私有区块链更中立,从而鼓励竞争。公共区块链实现的不受限制的访问与正在激增的孤立的许可区块链形成鲜明对比。虽然公共区块链有缺点,但有许多众所周知的解决方法可以解决它们的挑战,特别是通过在智能合约级别添加权限。 报告称,无需许可的区块链可以为 L2 区块链(包括受监管的区块链)提供互操作性层。当智能合约位于单个链上时,它们能够组合成更复杂的功能。 同时,报告也提到了公共区块链的缺点,例如可扩展性、隐私性、终结性和治理。它深入研究了每个主题,以及有争议的 MEV 问题。