Solidity智能合约编程漏洞及对策

简介:

上溢(Overflow)和下溢(Underflow)

Solidity能处理256位的整数。所以 2²⁵⁶-1 加1就会为0.这个就是Overflow

0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ 0x000000000000000000000000000000000001
----------------------------------------
= 0x000000000000000000000000000000000000

在Solidity中如果使用无符号整数,那么0减1就会得到最大的整数

0x000000000000000000000000000000000000
- 0x000000000000000000000000000000000001
----------------------------------------
= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

对策是使用SafeMath库来做数学运算

 

Solidity可见性修饰符之差别

Public函数可以被任意调用(本合约的方法,被继承的合约方法,以及其他合约方法)

External函数不能被本合约方法调用

Private函数只能在本合约中被调用

Internal函数,稍微宽松一点,可以被本合约和继承合约的函数调用

Delegate Call是一个消息调用,需注意的是目标地址上的代码是运行在调用合约上下文当中的。这意味着调用的合约,可以在运行时动态的引入其他地址上的代码(模块化设计,对吧?),但是运行在调用合约的上下文中,以为着Storage, Balance, 和Current Address都是用的当前合约的

在下例中,攻击者可以通过在Delegation的上下文中调用Delegate合约中Public的PWN函数,从而获得合约的控制权

pragma solidity ^0.4.11;

// Credits to OpenZeppelin for this contract taken from the Ethernaut CTF
// https://ethernaut.zeppelin.solutions/level/0x68756ad5e1039e4f3b895cfaa16a3a79a5a73c59
contract Delegate {

  address public owner;

  function Delegate(address _owner) {
    owner = _owner;
  }

  function pwn() {
    owner = msg.sender;
  }
}

contract Delegation {

  address public owner;
  Delegate delegate;

  function Delegation(address _delegateAddress) {
    delegate = Delegate(_delegateAddress);
    owner = msg.sender;
  }
  
  // an attacker can call Delegate.pwn() in the context of Delegation
  // this means that pwn() will modify the state of **Delegation** and not Delegate
  // the result is that the attacker takes unauthorized ownership of the contract
  function() {
    if(delegate.delegatecall(msg.data)) {
      this;
    }
  }
}

Parity Hack同时错用了修饰符和Delegate Call。一个可以修改合约控制权的函数被设为Public。这就给黑客开了后门:定制虚假的msg.data来获得合约控制权。

msg.data里是要调用函数的签名=sha3 (alias for keccak256)的头8个字节。

web3.sha3("pwn()").slice(0, 10) --> 0xdd365b8b

如果函数有一个参数, pwn(uint256 x):
web3.sha3("pwn(uint256)").slice(0,10) --> 0x35f4581b

 

重入/Reentrancy问题(THEDAO Hack)

在以下的代码中,Call函数会等待直到所有的Gas都是用掉了。但是Sender和真正扣钱是有时间差的。

这就好比,你走进银行,找柜员取现金1000RMB,你的账户正好有1000RMB. 所以第一次,柜员会给你1000RMB。在柜员还没有来的及操作从你的账户中扣1000RMB,你再问柜员要1000RMB,柜员一查,发现你的账户上有1000RMB(因为还没有来得及扣掉),柜员会又给你1000RMB

function withdraw(uint _amount) public { 
    if(balances[msg.sender] >= _amount) { 
        if(msg.sender.call.value(_amount)()) 
          { _amount; } 
        balances[msg.sender] -= _amount; 
    } 
}

对策是:先扣钱,再送钱。另外一种方法是使用Mutex。

现在最好的方法是msg.sender.transfer(_value) . 如果确实要使用send ,用require(msg.sender.send(_value));

以太坊智能合约 —— 最佳安全开发指南

 

   参考: 

        文章1

        文章2

相关文章
|
5月前
|
安全 算法 定位技术
[Solidity][区块链安全入门]Solidity语言关于密码学知识的运用以及存在漏洞
密码学在区块链中扮演关键角色,确保机密性、完整性、身份认证和不可否认性。对称密钥加密用于快速加密,但不支持不可否认性。非对称加密(如RSA)解决了这一问题,每个用户拥有公钥和私钥。散列函数(如SHA-1、SHA-2)用于数字签名,保证信息来源和完整性。同态加密允许在不解密情况下处理加密数据,增强隐私保护。零知识证明则能验证信息正确性而不泄露额外信息,如ZCash使用该技术隐藏交易详情。环签名技术(如在门罗币中)隐藏签名者身份。区块链隐私保护措施包括混币技术,旨在混淆交易路径。网络和应用层面上也存在隐私挑战,需要综合策略来防御。
|
5月前
|
存储 安全 区块链
智能合约开发中13种最常见的漏洞
智能合约开发中13种最常见的漏洞
702 5
|
5月前
|
开发框架 安全 测试技术
如何进行智能合约的安全测试
如何进行智能合约的安全测试
75 7
|
5月前
|
监控 安全 区块链
智能合约中随机数生成漏洞
智能合约中随机数生成漏洞
49 4
|
安全 区块链 数据安全/隐私保护
迪斯卡(Disca)众筹质押挖矿系统项目开发/Solidity编写
迪斯卡(Disca)众筹质押挖矿系统项目开发/Solidity编写
|
存储 前端开发 JavaScript
区块链智能合约编程语言 Solidity
上文介绍了[区块链生态发展](https://wangbinguang.blog.csdn.net/article/details/131440404),我们知道以太坊的到来可以使开发人员基于区块链开发DApp,本文介绍 Solidity 编程语言的使用,然后基于 Solidity 编写一个简单的智能合约。
128 1
|
JSON IDE Serverless
DAPP智能合约质押挖矿开发程序丨DAPP智能合约质押挖矿系统开发(正式版)丨DAPP智能合约质押挖矿源码功能
  本质上来说,智能合约是一段程序,它以计算机指令的方式实现了传统合约的自动化处理。智能合约程序不只是一个可以自动执行的计算机程序,它本身就是一个系统参与者,对接收到的信息进行回应,可以接收和储存价值,也可以向外发送信息和价值。
|
监控 安全 机器人
量化合约系统开发(功能说明)丨dapp智能合约开发(技术详解)
量化交易也是一种交易。狭义上的量化交易指将交易条件转化为程序,并自动下单;广义的量化交易是系统交易方式,是一种综合交易系统,根据一系列交易条件,智能决策系统,将丰富的经验与交易条件相结合,管理交易过程中的风险控制。
量化合约系统开发(功能说明)丨dapp智能合约开发(技术详解)
|
存储 区块链 数据库
Solidity开发智能合约
一个简单的智能合约 在Solidity中,一个合约由一组代码(合约的函数)和数据(合约的状态)组成。合约位于以太坊区块链上的一个特殊地址。
1518 0
|
存储 JavaScript 前端开发
【智能合约】Solidity 基础知识 | 以太坊智能合约编程语言
目录 注意事项 编译器选择 一些说明 1. 变量 1.1 状态变量 1.2 局部变量 2. 数据类型 2.1 值类型 2.1.1 布尔类型(Booleans): 2.1.2 整型(Integers): 2.1.3 定长浮点型(Fixed Point Numbers): 2.1.4 定长字节数组(Fixed-size byte arrays) 2.1.5 有理数和整型常量(Rational and Integer Literals) 2.1.6 枚举(Enums) 2.1.7 函数类型(Function Types) 修饰符 函数定义 函数返回值 构造函数 2.1.8 地址类型(Address)
417 0
【智能合约】Solidity 基础知识 | 以太坊智能合约编程语言