智能合约安全性

智能合约安全性必须被视为任何其他应用程序安全性,它可能包含逻辑漏洞,不安全的设计,并且可能在易受攻击的组件(分类帐)上运行。然而,智能合约是以太坊区块链的核心元素,与其他软件概念不同,它受到几种区块链技术原语的约束:

  • 智能合约运行时是沙盒,这意味着获得安全的随机源很难。
  • 智能合约可以持有,转移或销毁资金,使其成为经济风险的组成部分。
  • 除非从设计阶段引入升级机制,否则无法直接升级智能合约。
  • 智能合约是不可变的,并具有不可撤销的自毁功能。
  • 智能合约可以拥有一个或多个所有者。

一、所有权:

与传统软件管理流程不同,智能合约支持以下技术强制所有权模型:

单一所有权:合同中有一个所有者负责合同管理流程。

共同托管所有权:适用于N方网络中两方或多方之间的协议,任何一方均可单方面对合同采取行政行动。

基于联盟的所有权:是一种扩展共享托管所有权的形式,需要就行政行为达成共识。

二、安全模式:

检查 - 效果 - 交互模式:与其他合同的交互应始终是合同功能的最后一步。至关重要的是,当前合同在处理对其他合同的控制之前已完成其功能,并且不依赖于其他合同的执行。

断路器:是逻辑紧急停止执行逻辑。在智能合约逻辑中实施紧急停止是一种很好的安全措施。断路器可以由合同中包含的受信任方(如合同所有者)手动触发,也可以使用程序化的一致性规则在满足定义的条件时自动触发断路器。

限速:一段时间内的智能合约功能可以更好地控制可能被滥用的资源。

速度颠簸:在操作执行中引入延迟,允许在操作被视为恶意时采取行动。

三、常见合同漏洞

重入:当初始执行完成之前允许外部合同调用对调用合同进行新调用时,就会发生入。对于函数,这意味着合同状态可能由于调用不可信合同或使用具有外部地址的低级函数而在其执行过程中发生变化。

访问控制:虽然不安全的可见性设置为攻击者提供了直接访问合同私有值或逻辑的方法,但访问控制旁路有时更为微妙。当合同使用不推荐的tx.origin来验证调用者,处理冗长需求的大型授权逻辑并在代理库或代理契约中不计后果地使用delegatecall时,可能会发生这些漏洞。

算术:整数溢出和下溢不是一类新的漏洞,但它们在智能合约中尤其危险,其中无符号整数很普遍,大多数开发人员习惯于简单的int类型(通常只是有符号整数)。如果发生溢出,许多良性看似的代码路径将成为盗窃或拒绝服务的载体。

未经检查的低级别调用:Solidity的一个更深层的功能是低级函数,如call(),callcode(),delegatecall()和send()。它们在计算错误时的行为与其他Solidity函数完全不同,因为它们不会传播(或冒泡)并且不会导致当前执行的完全恢复。相反,它们将返回一个设置为false的布尔值,代码将继续运行。这可能会给开发人员带来惊喜,如果不检查此类低级别调用的返回值,则可能导致失败打开和其他不必要的结果

糟糕的随机性:很难在以太坊中得到正确的结果。虽然Solidity提供的函数和变量可以访问明显难以预测的值,但它们通常要比看起来更公开。因为随机源在以太坊中可以预测,恶意用户通常可以复制它并依赖于其不可预测性来攻击函数,这也适用于构建在Quorum之上的dApp。

前跑:在公共以太坊客户矿工总是通过代表外部地址(EOA)运行代码的燃气费获得奖励,用户可以指定更高的费用来更快地开采他们的交易。由于以太坊区块链是公开的,所以每个人都可以看到其他待处理交易的内容。这意味着如果给定用户显示解谜或其他有价值的秘密的解决方案,恶意用户可以窃取解决方案并以更高的费用复制他们的交易以抢占原始解决方案。如果智能合约的开发人员不小心,这种情况可能导致实际和破坏性的前端攻击。另一方面,由于Quorum在其一致性算法中不使用工作证明(PoW)且气体成本为零,因此在Quorum之上构建时,PoW挖掘相关的漏洞不适用,

时间操纵:从锁定代币销售到在特定时间解锁资金,合同有时需要依赖当前时间。这通常通过block.timestamp或其别名现在在Solidity中完成。在公共以太坊中,这个价值来自矿工,但是在Quorum中,它来自minter或者验证者,因此聪明的合同应该避免强烈依赖于关键决策的阻滞时间。请注意,block.timestamp不应用于生成随机数。

短地址:攻击是EVM本身接受错误填充参数的副作用。攻击者可以通过使用特制地址来利用这一点,使编码不良的客户端在将参数包含在事务中之前对参数进行错误编码。

四、安全检查表

4.1 所有权

  • Enteprise Blockchain中不得禁止所有者联系。

  • 合同必须包括启动阶段,其中所有所有者都被明确识别和设定init(owners_list)

  • 在开始设计智能合约逻辑之前确定合同所有权模型。

  • 为基于Constortium的所有权定义共识模型。

  • 合同可升级性和所有权功能必须验证新地址是否有效。

  • 必须向所有网络参与者广播所有权相关事件。

  • 在基于Constortium的所有权结构中,更改在提交之前必须获得Constortium成员批准的活动(例如,编辑Constortium结构)必须具有批准的到期日期。

  • 基于Constorium的投票必须涉及通过EVM事件emition的实时通知。

4.2 合同执行

  • 合同应使用锁定的编译器版本

  • 编译器版本应该在所有合同中保持一致

  • 合同不应该遮蔽或覆盖内置函数

  • 合同不应该使用tx.origin作为授权机制

  • 合同不应该使用时间戳作为随机源

  • 契约不应该使用块号或哈希作为随机源

  • 合同绝不应使用块号或时间戳作为关键决策条件

  • 合同不应该滥用多重继承

  • 修饰符必须遵守合同状态或执行外部呼叫

  • 合同不应包含跨职能竞争条件

  • 合同不应该使用简单的算术运算,而应该使用安全的数学运算

  • 合同回退功能应该没有可能引入安全隐患的未知状态

  • 合同应该避免阴影变量

  • 应审查合同公共变量/功能,以确保适当的可见性

  • 合同私有变量不应包含敏感数据

  • 合同函数应明确声明可见性

  • 合同公共职能应执行适当的授权检查

  • 合同应验证所有公共和外部职能的输入

  • 使用旧的可靠性版本构造函数名称的合同必须与合同名称匹配

  • 合同应明确标明不受信任的合同为“不受信任”

  • 合同函数逻辑应在进行外部调用之前执行状态更改操作

  • 合同逻辑应尽可能使用send()和transfer()over call.value

  • 应妥善处理delegatecall的合同使用

  • 合同逻辑必须正确处理任何外部调用的返回值

  • 合同绝不能假设它的余额为0

  • 合同逻辑不应包含易受拒绝服务攻击的循环

  • 多方合同逻辑行动不应该依赖于单一方

  • 防止Toke转移到0x0地址

你可能感兴趣的:(智能合约安全性)