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种最常见的漏洞
658 5
|
5月前
|
开发框架 安全 测试技术
如何进行智能合约的安全测试
如何进行智能合约的安全测试
75 7
|
5月前
|
监控 安全 区块链
智能合约中随机数生成漏洞
智能合约中随机数生成漏洞
47 4
|
安全 区块链 数据安全/隐私保护
迪斯卡(Disca)众筹质押挖矿系统项目开发/Solidity编写
迪斯卡(Disca)众筹质押挖矿系统项目开发/Solidity编写
|
存储 前端开发 JavaScript
区块链智能合约编程语言 Solidity
上文介绍了[区块链生态发展](https://wangbinguang.blog.csdn.net/article/details/131440404),我们知道以太坊的到来可以使开发人员基于区块链开发DApp,本文介绍 Solidity 编程语言的使用,然后基于 Solidity 编写一个简单的智能合约。
125 1
|
区块链 数据安全/隐私保护
一文读懂DeFi流动性挖矿系统开发原理(源码示例)
DeFi流动性挖矿主要发生在以太坊区块链上的产品中,它通过为以太坊上的DeFi产品提供流动性来赚取利润。可以简单地理解为用户通过存款代币获得被动回报,但如果他们想获得更高的回报,就需要对其进行管理。不同协议之间的回报有差异,即便是同一协议不同货币市场或代币池之间的收益也存在很大的差异。
|
JSON IDE Serverless
DAPP智能合约质押挖矿开发程序丨DAPP智能合约质押挖矿系统开发(正式版)丨DAPP智能合约质押挖矿源码功能
  本质上来说,智能合约是一段程序,它以计算机指令的方式实现了传统合约的自动化处理。智能合约程序不只是一个可以自动执行的计算机程序,它本身就是一个系统参与者,对接收到的信息进行回应,可以接收和储存价值,也可以向外发送信息和价值。
|
机器学习/深度学习 人工智能 自然语言处理
秒合约交易所系统开发实现技术分析及代码部署
 合约交易是指买卖双方对约定未来某个时间按指定价格接收一定数量的某种资产的协议进行交易,合约交易的买卖对象是由交易所统一制定的标准化合约,交易所规定了其商品种类,交易时间,数量等标准化信息。合约代表了买卖双方所拥有的权利和义务。
|
Rust 区块链 数据安全/隐私保护
佛萨奇2.0智能合约系统丨佛萨奇2.0智能合约系统开发(功能版)丨佛萨奇2.0智能合约现成源码案例开发
隐私计算网关调用系统合约把执行结果与签名传到链上。系统合约会从链上获取Enclave远程证明,从中提取出签名公钥,并对执行结果的签名进行验证,并从执行结果中提取隐私合约、链上数据部分,与区块链上的信息进行比对。如果这些验证都通过了,则系统合约执行成功,隐私合约的执行结果会被打包到区块中等待共识出块。