Solidity合约开发安全问题【TOP 10】

简介: 本文介绍CheckMarx安全研究小组通过扫描公开的以太坊智能合约所发现的Solidity智能合约开发中常见的十大安全问题,其中__未检查的外部调用__ 和 __高成本循环__ 分列排行榜前两名。该安全问题排行榜于2020年5月发布。

本文介绍CheckMarx安全研究小组通过扫描公开的以太坊智能合约所发现的Solidity智能合约开发中常见的十大安全问题,其中__未检查的外部调用__ 和 高成本循环 分列排行榜前两名。该安全问题排行榜于2020年5月发布。

在2018年,CheckMarx安全研究小组首次发布了Solidity智能合约开发中常见的十大安全问题排行榜,其中位居榜首的两个问题分别是__外部合约拒绝服务__ 和 重入 。2020年的情况已经有所变化,

下表比较了2018年和2020年Solidity十大常见安全问题之间的变化。这些问题按严重程度和流行程度排序:

在这里插入图片描述

用自己熟悉的语言学习 以太坊DApp开发Java | Php | Python | .Net / C# | Golang | Node.JS | Flutter / Dart

S1 – 未检查的外部调用

这是我们之前的Solidity十大安全问题榜单上第三常见的问题。由于现在解决了前两个问题,因此 未检查的外部调用 已升至2020年更新列表中最常见的问题。

Solidity低级调用方法,例如address.call(),不会引发异常。相反,如果调用 遇到异常,则它们返回false。另一方面,如果 doSomething()抛出异常,则合约调用(例如 ExternalContract.doSomething() )会自动传播异常。

使用addr.send()发送以太币是一个很好的例子,应该通过检查返回值来显式处理不成功的发送,但这对于其他外部调用也有效:

在这里插入图片描述

S2 – 高成本循环

代价高昂的循环从Solidity安全榜单的第四名上升至第二名。尽管我们以前的清单中的前2个问题都已解决,但受该问题影响的智能合约数量却增长了近30%。

以太坊环境的算力是需要付费的(使用以太币)。因此,减少完成操作所需的计算步骤不仅是优化的问题,而且还涉及成本效率。

循环是昂贵操作的一个很好的例子:由于数组中包含许多元素,因此需要更多迭代才能完成循环。如你所料,无限循环会耗尽所有可用GAS。
在这里插入图片描述

如果攻击者能够影响元素数组的长度,则上述代码将导致拒绝服务,从而阻止执行跳出循环。尽管它与十大常见问题相去甚远,但在扫描的智能合约中发现有8%的合约存在数组长度操纵问题。

S3 – 权力过大的所有者

这是Soldiity十大安全问题榜单中的一个新条目,该问题影响了约16%的已扫描智能合约。

某些合约与其所有者(Owner)紧密相关,使得某些功能只能由所有者地址调用,如下例所示:

在这里插入图片描述

只有合约所有者能够调用doSomething()doSomethingElse()函数:前者使用onlyOwner修饰符,而后者则显式执行该修饰符。这带来了严重的风险:如果所有者的私钥遭到泄露,则攻击者可以控制该合约。

S4 – 算术精度问题

由于使用256位虚拟机(EVM),因此Solidity的数据类型有些复杂。该语言不提供浮点表示形式,并且少于32个字节的数据类型将被打包到同一个32字节的槽位中。考虑到这一点,你应该会想到可能存在的精度问题:

在这里插入图片描述

如上例所示,在乘法之前执行除法时,可以预料存在很大的舍入误差。

S5 – 过于依赖tx.origin

智能合约不应依赖于tx.origin进行身份验证,因为恶意合约可能会进行中间人攻击,耗尽所有资金。
建议改用msg.sender

在这里插入图片描述
可以在Solidity的文档中查看Tx Origin攻击 的详细说明。简单的说,tx.origin始终是合约调用链中的第一个帐户,而msg.sender则表示直接调用者。如果链中的最后一个合约依赖于tx.origin进行身份验证,那么调用链中间环节的合约将能够榨干被调用合约的资金,因为身份验证没有检查究竟是谁(msg.sender)进行了调用。

S6 – 上溢出/下溢出

Solidity的256位虚拟机(EVM)存在上溢出和下溢出问题,具体演示可以查看这里。在for循环条件中使用uint数据类型时,开发人员要格外小心,因为它可能导致无限循环:

在这里插入图片描述

在上面的示例中,当i的值为0时,下一个值为2^256 -1,这使条件始终为true。开发人员应当尽量使用<>!===进行比较。

S7 –不安全的类型推断

该问题在Solidity十大安全问题排行榜中上升了两个位置,现在影响到的智能合约比之前多出17%以上。

Solidity支持类型推断,但有一些奇怪的表现。例如,字面量0会被推断为byte类型,而不是我们通常期望的整数类型。

在下面的示例中,i的类型被推断为uint8,因为这时能够存储i的值的最小长度的整数类型。但如果elements数组包含256个以上的元素,则下面的代码就会发生溢出:

在这里插入图片描述
因此,我们建议显式声明数据类型,以避免代码意外的行为或错误。

S8 – 不正确的转账

此问题在Solidity十大安全问题榜单中从第六位下降到第八位,目前影响不到1%的智能合约。

在合约之间进行以太币转账有多种方法。虽然官方推荐使用addr.transfer(x)函数,但我们仍然找到了还在使用send()函数的智能合约:

在这里插入图片描述

请注意,如果转账不成功,则addr.transfer(x)会自动引发异常,这样可以减轻了先前讨论的未检查外部调用的问题S1。

S9 –循环内转帐

当在循环中进行以太币转账时,如果其中一个合约不能收到,那么整个交易将被回滚。

在这里插入图片描述

攻击者可能利用此行为来导致拒绝服务,从而阻止其他合约接收以太币。

S10 – 时间戳依赖性

在Soldity十大安全问题榜单中,该问题在2018年排名第五。

重要的是要记住,智能合约在不同时刻在多个节点上运行。以太坊虚拟机(EVM)不提供时钟时间,并且通常用于获取时间戳的now变量实际上是矿工可以操纵的环境变量(block.timestamp的别名)。

在这里插入图片描述

由于矿工当前可以操纵环境变量,因此只能在不等式><>=<=中使用其值。

如果你的应用需要随机性,可以参考RANDAO合约,该合约基于任何人都可以参与的去中心化自治组织(DAO),是所有参与者共同生成的随机数。

总结

在比较2018年和2020年的Solidity十大常见安全问题列表时,我们可以观察到有关开发最佳实践的一些进展,尤其是那些影响安全性的实践。看到2018年排名前2的问题,__外部合约拒绝服务__ 和 重入 离开前十名榜单是一个积极信号,但开发者仍然需要采取一些重要步骤来避免常见错误。


原文链接:Solidity十大安全问题 — 汇智网

目录
相关文章
|
9月前
|
算法 Python
合约/现货量化交易/合约交易/秒合约系统开发dapp技术搭建/Python代码规则示例
合约/现货量化交易/合约交易/秒合约系统开发dapp技术搭建/Python代码规则示例
|
3天前
|
区块链
关于代币合约项目系统开发DAPP模式方案【源码示例】
以下是一个简单的以太坊代币合约代码示例,它定义了一个名为 `Token` 的代币合约。在实际使用中,请确保您已获得适当的许可并遵循相关法规。
|
2月前
|
IDE 区块链 开发工具
智能合约开发环境搭建及Hello World合约
智能合约开发环境搭建及Hello World合约
61 1
|
12月前
|
安全 区块链
IPP Swap代币合约去中心化交易所系统开发实现技术详细/案例介绍/规则逻辑/方案项目/源码程序
  What is pledging mining?   Pledge mining refers to the process of locking digital currency onto the blockchain through specific security mechanisms to obtain profits.Investors obtain the benefits generated by network operations by selecting appropriate projects and locking in a corresponding numb
|
9月前
|
机器学习/深度学习 人工智能 自然语言处理
秒合约开发原理丨秒合约系统开发(详细规则)丨秒合约源码案例部署
秒合约开发原理丨秒合约系统开发(详细规则)丨秒合约源码案例部署
|
10月前
|
存储 区块链 数据安全/隐私保护
合约跟单丨合约交易丨秒合约项目系统开发(源码案例)
去中心化:在一个系统中任意节点的权利和义务都是均等的
|
11月前
|
安全 数据挖掘 测试技术
现有量化秒合约交易所系统二次开发合约源代码详情
event LogNewTrade(uint256 orderId, address player1, address player2, uint256 amount1, uint256 amount2);
|
12月前
|
存储 算法 TensorFlow
dapp/defi/IPP swap去中心化交易所系统项目开发(合约案例)
区块链技术中的分布式账本是实现去中心化的关键image.convertTo(image,CV_32FC3);
|
12月前
|
存储 设计模式 区块链
defi/dapp智能合约发行代币lp项目系统开发详细程序/源码功能/规则详细/方案设计
智能合约是一种自动化的计算机程序,在区块链技术中具有重要作用。它可以在不需要第三方的干预下执行合约,从而提高了合约执行的透明性、可靠性和安全性。智能合约是一种非常有前景的技术,它有着广泛的应用领域。随着其应用范围的不断拓展,智能合约将会成为未来区块链技术发展的关键因素之一