![]()
2026年2月1日,跨链桥CrossCurve(原EYWA)在Arbitrum、以太坊等链上被盗约300万美元。攻击者没用什么闪电贷或密码学新招——只是调了一个任何人都能调用的函数,往里塞了伪造的数据。
审计师看到这种漏洞会叹气。修复方案事后看极其明显,但它暴露的系统性问题远比单个协议严重。
跨链桥的"快递系统"是怎么被劫持的
CrossCurve用Axelar的通用消息传递(General Message Passing,GMP)来 relay 跨链消息。架构像一套快递系统:源链Portal合约锁仓并发出包裹,Axelar负责运输,目标链ReceiverAxelar签收并通知PortalV2放货。
整个系统的安全假设只有一个:只有真正的Axelar消息才能触发放货。
ReceiverAxelar有个expressExecute()函数,设计初衷是"快速通道"——绕过Axelar的共识验证,让用户更快拿到钱。问题就出在这里。
代码简化后长这样:
// 漏洞版本——来自CrossCurve的ReceiverAxelar function expressExecute( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes calldata payload ) external { // 唯一检查:这个commandId用过没? require(!executedCommands[commandId], "Already executed"); executedCommands[commandId] = true; // ⚠️ 没验证sourceChain真假 // ⚠️ 没验证sourceAddress是否在白名单 // ⚠️ 没多签 guardian 确认 // ⚠️ 没验证Axelar是否真的 relay 过这条消息 _executePayload(sourceChain, sourceAddress, payload); }
攻击者干了什么?自己生成一个随机的commandId,伪造sourceChain填"ethereum",伪造sourceAddress填Portal地址,payload写上"解锁100万USDC到我地址"。然后调用expressExecute。
合约只查了"这个commandId没用过",就乖乖执行了。
4层防线,CrossCurve一层都没设
Axelar GMP其实提供了完整的安全机制,但CrossCurve的expressExecute全部绕过了。对比正常的execute()函数:
function execute( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes calldata payload ) external { // Layer 1: Axelar验证者集确认消息真实性 require( axelarGateway.validateContractCall( commandId, sourceChain, sourceAddress, keccak256(payload) ), "Not approved by Axelar" ); // Layer 2: 源链白名单检查 require( whitelistedSourceChains[sourceChain], "Source chain not whitelisted" ); // Layer 3: 源地址白名单检查 require( whitelistedSourceAddresses[sourceAddress], "Source address not whitelisted" ); // Layer 4: 重放保护(commandId已用检查) require(!executedCommands[commandId], "Already executed"); executedCommands[commandId] = true; _executePayload(sourceChain, sourceAddress, payload); }
![]()
expressExecute()为了"快",把前三层全删了,只留了最后一层——而重放保护防的是同一消息被多次执行,不是假消息被执行。
这就像快递柜只检查"这个取件码没用过",却不验证取件码是不是系统发的、是不是发到正确手机号、包裹是不是从正规渠道来的。
攻击链还原:从第一笔到300万
链上记录显示,攻击者分多笔操作,横跨多条链:
第一笔:Arbitrum上调用expressExecute,伪造以太坊来源,解锁50万USDC。交易成功,系统没报警。
第二笔:换了个commandId,同样参数再来一次,解锁80万USDC。
第三至七笔:切换到Optimism、Base、BSC等链重复操作,单笔金额从20万到100万不等。
第八笔:尝试在以太坊主网操作时,CrossCurve团队紧急暂停合约。但此时损失已达约300万美元。
有趣的是,攻击者用的commandId生成方式很朴素——keccak256(abi.encode(block.timestamp, nonce))。没有精密计算,没有MEV抢跑,就是简单的"填个新数就行"。
这说明漏洞门槛低到什么程度:任何能写Solidity脚本的人都能复现。
跨链桥的结构性困境:快与安全不可兼得?
expressExecute的存在本身反映了跨链桥的产品压力。Axelar的正常execute()需要验证者集共识,通常要几分钟到十几分钟。DeFi用户等不了——套利机会转瞬即逝,流动性挖矿要抢头矿。
所以协议方做"快速通道",用抵押品或信誉担保来换取速度。CrossCurve的版本显然没设计好担保机制:任何人都能调用,没有质押要求,没有多签门槛。
![]()
对比其他桥的方案:
LayerZero的ULN(Ultra Light Node)用预言机+中继者双签,但配置不当也会出问题(2024年某协议就因预言机白名单配置错误被盗)。
Axelar自己的Express Service要求调用方预存抵押品,执行失败会罚没。CrossCurve没采用这个模式。
Wormhole的Guardian Network是17个验证者多签,但2022年也因验证者私钥泄露被盗3.2亿美元。
没有完美方案,只有风险转移。CrossCurve选择了"把风险转给代码正确性",然后代码错了。
修复与行业余波
CrossCurve在事件后48小时内部署补丁,expressExecute()添加Axelar验证调用,并启用源链/源地址双白名单。团队承诺赔偿方案,但具体比例未公布。
更深层的影响在于审计行业的反思。多位安全研究员在社交媒体指出,这种"显而易见"的漏洞为何能通过审计?
「」慢雾科技在事件分析中写道:「express模式的安全假设需要单独审计,不能默认底层协议(Axelar)会兜底。很多审计报告只看了标准流程,没覆盖快速通道的异常路径。」
CertiK同期发布的跨链桥风险指南将"express执行模式"列为独立审计项,建议强制要求:抵押品机制、多签 guardian、源地址白名单三层至少满足两层。
对普通用户的实际影响:CrossCurve锁仓量(TVL)从事件前的4200万美元跌至目前的800万美元,跌幅81%。资金用脚投票的速度,比任何安全报告都直接。
而那个被攻击者反复调用的expressExecute函数,现在已被重命名为expressExecuteWithValidation()——名字长了,但愿记性也长了。
当你下次在跨链桥看到"快速到账"选项时,会多想一想它的安全假设吗?
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.