Corda 平台的设计默认已经考虑到安全因素。但是不幸的是平台没办法避免每种安全的错误。这篇文章描述了当编写应用的时候,都要考虑哪些方面来阻止各种类型的攻击。我们假设对方会尝试着使用 flow 级别的攻击来破坏你的交易,当你可能要快速添加更多的合作伙伴并且没有过多的验证的时候,对于软件安全的依赖会让后来的维护工作变得很难。
Flows
编写 flows 是你的应用如何同网络中的其他节点进行沟通的方式。因此他们是恶意数据进入到你的应用的一个典型的入口,所以必须要谨慎地对待。
receive
方法返回的数据会被包装在 UntrustworthyData<T>
marker 类型中。这个类型并没有添加任何的方法,它被放在这仅仅是为了提醒你对于从网络中获得的任何信息都要正确的验证。记住,在另一端的节点可能并没有运行你提供给他的代码:他们被允许做任何事情!你需要注意的事情包括:
- 一个同部分的 transaction build 或者之前在 flow 中提出的 transaction 不匹配,比如你提出了一个对于某个资产(asset)价值 $100 现金 state 的交易,然后这个 transaction 从对方节点签了名被返回来,你必须要检查它确实只想了你真正请求的那个 state。否则的话如果黑客知道某个资产的 ID,那么他们会欺骗你为一个会花费你更多的 state 的 transaction 签名。
- 一个不是正确类型的 transaction。这里主要有两种 transaction 类型:通用类型和 notary 变更类型。如果你期望收到一种类型但是得到的是另外一种类型,那么你可能会发现自己为一个将自己的资产转移到了 恶意的一个 notary 的 transaction 提供了签名。
- 在一个 transaction 中的任何的 states 中存在非期望的变动。如果你对所有需要的数据都有访问权限的话,你可以重新运行 builder 逻辑,然后将结果 states 进行对比来确保它确实是你期望得到的。比如如果用来构建下一个 state 的数据对于双方都是可用的话,用来对你想要互相同意的 transaction 进行计算的方法可以在 flow 的两方被共享。
思路应该很清晰了:提供签名是一个非常敏感的操作,所以你必须要确定你将要提供签名的是什么,并且在 small print 中没有什么被改动了!一旦你向对方在一个 transaction 中提供了签名,你就没法做任何事情来阻止这些提交到账本中了。
合约
合约是在一个 JVM 沙盒(sandbox)中的任何的方法,因此 they have a lot of leeway to shoot themselves in the foot。需要关注的点包括:
- 在当前的 state 交换中是不允许 states 的变动的。你需要检查除了那些想要去改动的字段以外,是不应该有其他字段的变动的。
- 意外的捕获和忽略可能会由验证逻辑抛出来的异常。
- 如果你不知道其他的合约是什么或者会做什么的话,那么通过虚拟方法来调用其它的合约
网友评论