文档章节

以太坊智能合约开发常见的10个安全问题

区块链教程
 区块链教程
发布于 07/04 19:12
字数 2003
阅读 92
收藏 0

行业解决方案、产品招募中!想赚钱就来传!>>>

本文介绍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十大安全问题 — 汇智网

区块链教程

区块链教程

粉丝 6
博文 141
码字总数 246312
作品 0
深圳
私信 提问
加载中
请先登录后再评论。
beego API开发以及自动化文档

beego API开发以及自动化文档 beego1.3版本已经在上个星期发布了,但是还是有很多人不了解如何来进行开发,也是在一步一步的测试中开发,期间QQ群里面很多人都问我如何开发,我的业余时间实在...

astaxie
2014/06/25
2.7W
21
Web开发组件管理器--Bower

Bower 是一个针对Web开发的包管理器。该工具主要用来帮助用户轻松安装CSS、JavaScript、图像等相关包,并管理这些包之间的依赖。 功能有些类似于Component。不同之处是,Component是围绕Git...

匿名
2013/02/01
1.2W
2
跨平台 3D 游戏引擎--Castle Game Engine

Castle Game Engine 是一个用 Object Pascal 开发的跨平台 3D 游戏引擎。包含一个灵活的 3D 对象系统与开箱即用的水平,项目,智能生物等等。使用 X3D、VRML、Collada 和其他格式实现渲染和处理...

匿名
2013/02/05
2K
0
实时分析系统--istatd

istatd是IMVU公司工程师开发的一款优秀的实时分析系统,能够有效地收集,存储和搜索各种分析指标,类似cacti,Graphite,Zabbix等系统。实际上,istatd修改了Graphite的存储后端,重新实现了...

匿名
2013/02/07
2.7K
1
跨平台手机应用开发--Gideros

Gideros 可以让你轻松快速创建 iOS 和 Android 应用,提供用户友好的集成开发环境,内建模拟器对应用进行不同屏幕大小、分辨率下的测试,最大的优点是可即时修改代码即时进行测试,无需编译安...

匿名
2013/02/19
2.6K
0

没有更多内容

加载失败,请刷新页面

加载更多

spring集成kafka

1、引入依赖jar包 <dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId></dependency> 2、配置kafka信息 spring: kafka: bootstra......

简到珍
22分钟前
0
0
Spring Security 原理分析(一)

Spring Security 初始化 在普通的spring mvc 框架中,我们需要 @Configuration@EnableWebSecuritypublic class MyWebSecurityConfiguration extends WebSecurityConfigurerAdapter 手动添......

街角的小丑
29分钟前
18
0
查看 Linux 系统服务的 5 大方法

Linux 系统服务有时也称为守护程序,是在Linux启动时自动加载并在Linux退出时自动停止的系统任务。 在本文中,良许将为大家介绍如何列出 Linux 系统里所有运行的服务,以及如何检查某个服务的...

良许Linux
34分钟前
9
0
如何显示已上演的更改? - How do I show the changes which have been staged?

问题: I staged a few changes to be committed; 我上演了一些改变来承诺; how can I see the diff of all files which are staged for the next commit? 如何查看为下一次提交而暂存的所有...

技术盛宴
44分钟前
25
0
HashMap 的 defaultLoadFactor 的一种推导计算思路

1. 为啥需要 defaultLoadFactor 现在主流的 HashMap,一般的实现思路都是开放地址法+链地址法的方式来实现。 即数组 + 链表的实现方式,通过计算哈希值,找到数组对应的位置,如果已存在元素...

zhxhash
47分钟前
23
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部