上周三下午,一个匿名地址用一笔普通的USDC转账,悄悄解锁了MarketNow上所有AI代理技能。没有触发警报,没有拦截,就像用一张车票坐完了全世界的火车。而这一切,只是因为一个重复的交易哈希被系统再次接受。
两周前,MarketNow团队刚刚把产品推上线。这是一个让AI代理用USDC在Base链上买卖技能的市场,每一笔交易都在处理真实资金。在正式推广之前,他们决定做一件不常见的事——同时启动四项并行测试:安全渗透、性能负载、功能与国际化,以及SEO可发现性,然后把完整的审计报告开源,让挖出来的漏洞和修复方案直接暴露在公众眼前。
这件事立刻把人拉进了一个老派争论里:安全审计报告到底该不该完全开放?支持的一派认为,透明本身就是最好的防御,尤其是在加密世界里,闭口不谈漏洞往往是在给攻击者留后窗。而反对的声音则担心,公开的漏洞细节就像一张现成的攻击地图,修复之前的那几小时或几天足以造成实际损失。
不过,MarketNow的修复节奏让这两种声音都不得不重新掂量:他们在报告公开前,已经把四个致命级漏洞全部修好了,并且每一个都留下了详细记录。
第一个致命漏洞出现在“授权支出”环节。当AI代理购买技能时,系统会调用recordMandateSpend()去扣减授权额度,但这个调用漏掉了内部密钥,直接收到403拒绝。关键的问题是,即便支出扣减失败,许可证依然会照常发放。结果就是一个额度只剩10美元的代理,可以连续100次买下单价5美元的技能,总共烧掉500美元,而那个硬性上限彻底失效。修复方案很坚决:补上_internal: true和密钥参数,并且一旦扣款失败就直接抛错,让整个流程变成“故障关闭”模式——不扣款就不发许可证。
第二个漏洞藏在交易哈希的验证逻辑里。同一笔USDC转账的txHash,可以被反复拿来请求许可证,没有任何去重机制。这意味着,你只需要真的支付一次1美元,就能反复把这份转账记录当成凭证,把每个标价1美元的技能都免费领走。团队修复的手段是在GitHub的_data/used_txs/目录下建了一个去重仓库,每次签发许可证之前都先查一次哈希是否已经用过。
第三个漏洞在金额校验上犯了一个看似微小的错误:系统用的是“收到金额大于等于预期”的宽松比较,而不是必须完全相等。于是付一笔50美元的单次转账,后面所有单价不超过50美元的技能都可以重复兑换。修复直接切成了严格匹配:if (value !== BigInt(expectedAmountRaw)),差一分钱都不行。
第四个致命发现更接近一种身份劫持。系统验证了交易哈希的有效性,也验证了金额正确性,但从来没有检查过这笔USDC转账到底是谁发起的。攻击者只需要去Base区块链浏览器上扒一圈,找到所有转入平台钱包的USDC交易,然后用这些合法的哈希抢先兑换,就能在真正购买者还没来得及动手时,把对应技能的许可证占为己有。修复补上了一个最重要的身份绑定:验证链上交易的from地址必须与调用者的walletAddress完全一致。
除了这四个命中资金逻辑的致命漏洞,还有五个高危和七个中等级别的问题也在同一轮审计中被揪出来。高危和中危项的具体漏洞描述没有被逐一列明,但一系列加固动作已经看得出攻击面被收窄:许可证密钥从Math.random换成了crypto.randomBytes生成的随机数;Webhook地址加了白名单,只允许Slack、Discord、Telegram和Zapier,以此防范SSRF攻击;/api/*路径上统一加上安全头,设置nosniff、no-referrer和DENY策略。
此外,单页应用路由上部署了CSP头部;错误信息不再泄露RPC内部堆栈;每个技能购买默认加上单次购买上限,取min($50, 限额)而不是全限额放开;内部密钥如果缺失,系统直接进入故障关闭状态,不做任何后续操作。
渗透测试之外,性能压测和功能国际化审查也在并行推进,但这次公开的审计报告并没有放出具体的性能指标,只确认了并发用户下的负载表现已纳入测试范围。反倒是“目前仍然坦诚未解决”的列表,让人看到了这次开源审计的另一面诚意:实例级的内存限流器并不是全局方案,迁移到基于Upstash Redis的限流已列入路线图。
另外,USDC的不可逆特性带来链上托管的缺失,目前仍依靠手动争议处理,智能合约托管最早也要在2027年第一季度才会落地;单页应用每个路由返回的是同一份HTML,静态站点生成迁移也还在路上。
把这些未收尾的问题和已修复的列表并排摊开,其实正反双方最核心的论点都能找到证据。开源支持者可以指着四个致命漏洞的修复过程说:如果关起门修,可能永远不会有人知道资金逻辑里曾经藏着这么多可以绕过的缝隙。而反对者也可以指着尚待完善的清单说:在社区审视的目光下,未完成的部分同样被看得一清二楚。但或许正是这种两面的诚实,才让一场原本可能被藏起来的危机,变成了一次公开的安全加固。
热门跟贴