BM亲身传授小技能 防止第三方恶意消耗你的RAM

恶意第三方通过创建专用智能合约在部分用户和EOSIO合约不知情的情况下盗用了他们的RAM资源。通常,合约之间会相互告知某些事件,例如转账信息。通过对这个功能的滥用,恶意合约会在没有获得同意的前提下用任意数据填满其他人的RAM,并且让这些数据无法被释放。

基本情况

1.没有代币遭窃

2.经过合理部署的合约并不脆弱

3.治理过程可以修复代码

4.BP(区块生产者)采用升级的方式能够提供更好的保护

5.长期的更新习惯可以让默认行为变得更加安全

没有代币丢失状况

这个恶意的合约利用了智能合约开发者和用户在研发和使用智能合约时产生的误解。本次攻击更像是蓄意的破坏行为,而不是盗窃。一旦EOS治理流程能够审查并且改善这一状况,这类攻击就不会对受害者造成长期影响。

防止滥用的最佳方式

每个用户都应该检查他们的合约,或者委托可信的第三方代表他们检查相关合约。也就是说,对于那些使用通知(notification)功能的合约应该倍加小心。其中一个例子就是向那些他们并不信任的合约发送代币,同时其账户还持有CPU和RAM资源。

以编程方式发送代币到不可信的第三方账户的开发者应该通过没有可用RAM资源的账户转发(relay)这笔交易。这一点对于负责处理用户取现的中心化交易所和采用智能合约交易的去中心化交易所都适用。目前可信的转发合约有好几种。

很多钱包供应商都已经开始采取行动提醒用户,发送交易可能会消耗RAM。

通过治理流程释放被消耗的RAM

我认为用户和开发者所理解的“代码的目的”应该被执行。如果恶意的合约明显利用了用户的目的和代码的实际效果之间的差异,那么BP在仲裁恶意合约创建者和交互者的争议时,有权将这种恶意合约加入黑名单。

如果在仲裁过程中发现代码的行为与代码使用者意图相悖,那么BP有权更新代码,尽可能地使其行为与使用者的目的相符。在这种情况下,这些代码经过升级之后就能够释放那些被滥用的RAM,并保证未来不再滥用RAM。

EOSIO为什么包含这个功能?

这个功能可以催生很多有效用例,但同时也遭到了滥用,造成了RAM的消耗。其中最基础的用例就是需要接收用户存入资金的游戏合约。要处理代币合约的转账申请,交易所会部署相应的代码,接着用交易所账户的余额向发送方发出指定数额的代币。在这种情况下,交易所和存入资金的用户都可以授权交易所合约消耗该用户的RAM。交易所不会用自己的RAM存储用户的资金,因为这样可能触发攻击,导致大量的账户向该交易所发送dust(数额极低的)余额。

EOSIO还包含一个相关的功能,即“联机动作”(inline actions)。作为当前交易的一部分,这个功能允许一个合约调用另一个合约的代码。和通知功能不同的是,联机动作仅限于分配合约资源。

防止不可预知的行为

尽管现有的设计创造了很多合理的应用,但我们认为代码的默认运作行为是和用户及开发者的判断相反的。我们必须采取措施防止滥用,实现普通应用的复杂化以及非常见应用的简单化。

我们建议,通知处理者只能消耗那些已经接到通知的合约的RAM。这样才能保证用户在发送代币的同时不用担心RAM被故意消耗。交易所也能安全处理提现申请,不需要反复检查用户账户中的合约。

另外,现有的合约在消耗部分用户RAM之前必须获得直接授权。交易所合约在接收用户资金之前将要求用户“申请账户为自己的余额预留空间”。这样一来,后续的存入申请只会增加预先分配的RAM空间而不是直接分配新的RAM。

更新计划

我们正在准备一个只需要BP采用的更新,其将通过改变默认行为来阻止通知(例如代币转账通知)接收方意外消耗发送方的RAM。如果所有的BP都采用了这个升级,那么缓解滥用的策略就不太必要存在了。不幸的是,这种缓解方案可能打断有效的合约,除非这些合约能够完成更新,在通知处理期间不需要依赖于用户账户上的RAM配置。

所幸合约的升级方式相对比较简单。

节点在下一场公投中决定是否接受这次升级。

结论

EOSIO是按照其设计模式运作的,只要使用得当就非常安全。我们认为我们可以合理使用EOSIO,让大多数用例变得更加简单。我们正在和EOS社区合作,旨在开发更全面且更稳定的解决方案。

发表评论

相关文章