Nym 混合网络与代币解锁合约安全审计

Nym 混合网络与代币解锁合约安全审计

2 分钟 阅读

背景

2022 年 12 月,Nym 接受了由 Oak Security 开展的独立安全审计。Oak Security 是一家位于德国的网络安全咨询公司,专注于第三代区块链和去中心化协议的安全审计。 Oak Security 在 Cosmos、Terra、Polkadot 和 Flow 等生态中拥有丰富的审计经验。本次审计中,Oak Security 受托评估 Nym 生态系统的两个关键组件:(1)Nym 的混合网络(mixnet)与代币解锁合约(vesting)(参见完整报告),以及(2)Nym 钱包(参见完整报告)。 本次审计旨在评估这些组件的稳健性、识别潜在漏洞,并确保其代码开发过程符合最佳实践。 为便于读者理解,我们已按组件各自整理和呈现对应的审计发现。 您可以在此处查看 Nym 钱包的审计摘要。

Oak Security 对 Nym 混合网络(Mixnet)与代币解锁合约(Vesting)的审计摘要

此次审计历时两周,由一支由 4 名专家组成的团队完成。 Nym 团队向 Oak Security 提供了项目代码库的完整访问权限、详尽的项目规范以及相关支持文档。 本次审计的范围涵盖了 contracts/mixnet 与 contracts/vesting 代码库,以及这些合约在 Nym 的混合网络(mixnet)与代币解锁合约(vesting)中所使用的相关依赖与导入模块。

Oak Security 对代码进行了全面审查,结合自动化的源代码与依赖分析,以及逐行的人工检查,以发现安全漏洞、评估代码质量,并验证其是否符合安全编码原则。 这一全面的审计方法涵盖了对多个关键领域的深入分析,包括竞态条件漏洞、下溢与上溢问题、密钥管理实践、密码学稳健性、数据泄露风险、密码处理方式,以及访问与授权控制等。

本次审计的重点在于确保协议功能的正确性,识别任何可被利用的漏洞或智能合约缺陷,并提出改进建议以提升代码的安全性与可读性。

调查结果概述

Nym 的混合网络(mixnet)与代币解锁合约(vesting)具有高度的可读性与清晰度,并配备了完善的测试覆盖,从而有效提升了其可靠性。 在此次评估中,审计团队共识别出 19 项发现,其中包括 9 个安全漏洞——涵盖关键级与重大级问题——以及 10 个被归类为次要或信息性的一般性弱点。

Nym 团队已迅速修复所有关键级和重大级问题。 Oak Security 团队已对我们的修复进行验证并予以通过。

NYM-MIX-VEST-CONTRACT-1:周期(Epoch)或间隔(interval)事件执行失败会永久阻塞周期(epoch)的推进(高危级)

审计团队在测试 contracts/mixnet/src/interval/transactions.rs 中对 AdvanceCurrentEpoch 消息的处理机制时识别出了一个漏洞。 一个顺序循环在交易上下文中直接处理所有待执行事件,这意味着只要其中任意一个事件执行失败,就会导致整个交易回滚,从而有效地阻断周期与区间的推进,使协议陷入停滞状态。

为解决该问题,审计团队建议将事件执行封装在带有回复策略的子消息中。 这种处理方式使系统能够优雅地应对事件失败(handle failures gracefully),而不会导致整个交易被回滚。 然而,我们有意选择不采纳该建议。 在事件执行过程中出现失败意味着存在严重的逻辑缺陷,可能危及奖励机制的正确性。因此,与其冒着系统在损坏状态下继续运行的风险,不如暂停周期(epoch)的推进以便进行人工检查。 相反,我们在 Nym API 接口中实现了增强的监控机制,用于检测并提醒我们注意周期(epoch)推进失败的情况。 这种方式能够确保此类失败被及时标记,从而使我们能够迅速介入并解决相关问题。

NYM-MIX-VEST-CONTRACT-2:攻击者可以在未经孤立的混合节点(orphan mix nodes)同意的情况下强制其加入某个家族(family),从而在同一层中聚合大量节点(高危级)

在 JoinFamilyOnBehalf 消息中识别出一个漏洞,该漏洞可能使攻击者在未经节点同意的情况下将某个混合节点加入某个家族。 通过创建一个恶意家族,并使用受害混合节点的身份密钥(由其私钥签名)作为签名,攻击者可以将该节点困在该家族中。 这可能使攻击者能够将孤立的混合节点聚集到同一个家族中,通过在同一层集中大量节点来破坏网络结构,并提高其对路由过程施加影响的可能性。

为解决 JoinFamilyOnBehalf 消息中的漏洞,我们重新设计了合约的签名机制。 签名机制不再仅仅对混合节点的身份进行签名,而是更新为对包含明确意图与唯一随机数(nonce)的消息进行签名。 此项改动确保签名无法被重复使用或重放。

NYM-MIX-VEST-CONTRACT-3:在处理 TrackUndelegation 消息时存在无界迭代的问题,这可能导致用户无法进行撤销委托操作,并永久阻碍周期(epoch)的推进(高危级)

TrackUndelegation 消息中的无界循环(未限制迭代次数)在处理拥有大量委托的账号时可能会耗尽气费,从而导致用户无法进行解委托操作。 此类失败同样会阻断周期的推进,使协议停滞在当前状态。

为解决该问题,我们对每个账号设置了最多 25 个归属委托(vesting delegations)的限制。 该解决方案基于当时观察到的归属委托数量的最高值而制定的。

**更新:**自 2024 年起,已全面禁用归属委托。

NYM-MIX-VEST-CONTRACT-4:攻击者可以对 BondMixnodeOnBehalf 和 CreateFamilyOnBehalf 消息进行抢跑(front‑run),并修改其负载内容(高危级)

该漏洞使攻击者能够抢跑 BondMixNodeOnBehalf 和 CreateFamilyOnBehalf 消息,提取其中的签名并篡改其负载内容。 在 BondMixNodeOnBehalf 的情况下,攻击者还可以将自己设置为代理,从而获得对已注册的质押的完全控制权。

为解决该漏洞,我们实施了一个由两部分组成的修复方案。 首先,我们应用了 NYM‑MIX‑VEST‑CONTRACT‑2 中描述的签名生成改动,为签名加入了明确的意图字段以及唯一的随机数(nonce)。 其次,我们将合法代理地址限制为仅归属账号本身,从而确保攻击者无法将自己设置为代理并非法控制质押凭证。

更新:自 2024 年起,所有代理操作均已被禁用,使该攻击不再具有适用性。

NYM‑MIX‑VEST‑CONTRACT‑5:在“代理“(on behalf)交易中,签名可以被重放,从而使攻击者能够冒充用户(高危级)

该漏洞允许在“代理“(on behalf)交易中重放签名,使攻击者能够冒充用户。 由于签名仅包含原始数据,而没有包含诸如随机数(nonce)或消息标识符等额外的元数据,攻击者可以将某条消息中的签名重复用于另一条消息,从而强制移除家族成员。 此外,攻击者还可以在同一消息类型中重复使用签名,使某个成员能够使用同一份签名多次重新加入某个家族。

该问题的解决方案与 NYM‑MIX‑VEST‑CONTRACT‑4 中所采用的修复方式一致。

NYM-MIX-VEST-CONTRACT-6:(所有者、代理)对的密钥生成可能导致碰撞(高危级)

该漏洞将允许两个不同的(所有者、代理)地址对在 generate_owner_storage_subkey 函数中生成相同的异或(XOR)结果,从而可能导致密钥碰撞和数据覆盖。

将合法代理仅限制为归属(Vesting)合约地址这一解决方案(该方案曾应用于 NYM-MIX-MIX-VEST-CONTRACT-4),同样修复了此漏洞。 通过确保异或(XOR)运算始终针对常量字符串进行,该修改有效消除了碰撞风险。

NYM-MIX-VEST-CONTRACT-7:如果在同一个区块内处理了多个质押/委托(Delegation),track_delegation 可能会覆盖已有的委托数据(高危级)

该问题会导致在同一个区块内进行多次委托(Delegation)时发生密钥碰撞,进而可能导致 save_delegation 函数覆盖已有委托,最终造成先前委托数据的丢失。

为了修复此漏洞,我们重构了 save_delegation 函数的逻辑,在写入新委托之前会优先读取已存在的委托数额(进行累加/更新)。 若该键值(Key)已存在对应的委托记录,系统会先获取当前委托额度,与新委托额度进行累加后再写入更新后的总额,以防止现有委托被意外覆盖。

NYM-MIX-VEST-CONTRACT-8:如果保证金/质押(Bond)是由代理“代为”创建的,则该保证金所有者将无法执行操作(高危/高风险)

该问题会导致:如果保证金/质押(Bond)是“代为”创建的,且当前交易是由所有者(Owner)而非代理(Proxy)发起的,则该质押所有者将无法对其质押执行任何操作。 鉴于代理(Proxy)可能会遭到攻击(被破解)或丢失,且所有者(Owner)无法对其进行更换,这可能导致所有者永久失去对其保证金(Bond)的控制权。

我们并不认为这是一个漏洞或者问题,因为这是符合设计的预期行为。 当混合节点(Mix Node)通过归属(Vesting)合约进行质押(Bond)或委托(Delegation)时,后续针对该质押或委托的所有交互,均预期仅能通过该归属合约来进行。

更新:截至 2024 年,归属(Vesting)合约已被移除。

NYM-MIX-VEST-CONTRACT-9:如果大量混合节点(Mix Node)属于同一个家族(Family),执行 LeaveFamily 和 LeaveFamilyOnBehalf 消息可能会失败(高危)

该问题会导致在对 MEMBERS 映射(Map)中的大量家族成员进行遍历时因气费(Gas)耗尽,从而导致 LeaveFamily 和 LeaveFamilyOnBehalf 消息执行失败。 这将导致混合节点(Mix Node)无法退出家族(Family),从而使其被锁死在当前家族中。

**解决方案:**修复措施重构了底层逻辑,改为直接查询 MEMBERS 映射来校验指定混合节点的家族成员身份(从而避免了全局遍历与气费耗尽的风险)。 此项修复消除了对数组/映射的循环遍历,彻底避免了因气费耗尽(Out-of-Gas)引发的交易失败;同时确保即便在家族规模极大的情况下,节点成员依然能够成功执行退出操作。

更新:截至 2024 年,节点家族(Node Family)功能已被移除。

致谢

我们谨向 Oak Security 团队在本次审计全流程中所付出的专业努力与卓越贡献致以诚挚谢意。 我们对贵方在本次审计的筹备规划与具体实施阶段所展现出的高度协同与卓越专业性表示由衷赞赏。 保障系统安全是我们贯穿始终的重中之重。展望未来,我们将继续深化与业内顶尖安全团队的合作,共同为生态系统的稳健发展夯实最高标准的安全防线。

分享