大数跨境

【学习专栏】如何保护您的智能合约:6 个 Solidity 漏洞以及如何避免它们(上)

【学习专栏】如何保护您的智能合约:6 个 Solidity 漏洞以及如何避免它们(上) FastDaily
2022-04-11
2
导读:每天进步一点

转载请微信联系:huangdiezi,更多DAOWeb3NFTMetaverse资讯请关注老雅痞👇

源Georgios Konstantopoulos

亲爱的朋友们,大家好,我是公众号老雅痞的小编波动,雅痞哥为了敦促我学习区块链/DAO/NFT知识,我们将单独开始一个专栏,从零开始学习。每天在公众号FastDaily和老雅痞各更新一篇。


让我们每天学点新东西,争取不白活。


欢迎大家和我一起学习进步(微信yaoyaobigc)~揪咪~

在之前的学习中,我们了解了以太坊可扩展性的未来。现在假设所有这些可扩展性问题现在都已解决,并且以太坊的智能合约可以正常工作。

这些用户是善意的,还是他们可能是干扰合约顺利运行的对手?

智能合约是“不可变的”。一旦部署它们,它们的代码就无法更改,因此无法修复任何已发现的错误。

在一个潜在的未来整个组织都由智能合约代码管理, 非常需要适当的安全。过去的黑客攻击,例如TheDAO 或今年的 Parity hack (七月,十一月) 提高了开发者的意识,但这远远不够。

“这是黑客的迪士尼乐园”

在本文中,我们将介绍一些著名的安全陷阱及其缓解措施。

1. 上溢和下溢

当一个数字增加超过其最大值时就是溢出。举个例子,Solidity 最多可以处理 256 位数字(最多2²⁵⁶-1),因此增加 1 将导致 0。

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

达到最大读数后,里程表或行程表从零重新启动,称为里程表翻转。

同样,在相反的情况下,当数字为无符号 unsigned 时,递减将使数字下溢,从而产生最大可能值。

0x0000000000000000000000000000000000000
- 0x000000000000000000000000000000000001
----------------------------------------
= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

尽管这两种情况都很危险,但下溢情况更有可能发生,例如在代币持有者拥有X个代币但试图花费 X+1的情况下。如果代码没有检查,攻击者最终可能会被允许超额花费并拥有一个最大化的余额

缓解措施:一段时间以来,使用 OpenZeppelin 的SafeMath 库已成为标准做法。

2. 可见性和委托调用

如果在 7 月份你关注过类似问题的人,这个 bug 应该很熟悉,毕竟这是 Parity 钱包黑客事件,让用户损失了大约 3000 万美元。

Solidity 可见性修饰符及其区别。

任何人都可以调用公共函数(通过合约内部的函数、继承合约的函数或外部用户)

外部函数只能被外部访问,这意味着它们不能被合约的其他函数调用。下面的要点没有编译,外部可见性cannotBeCalled不允许它被合约的函数调用(但是它可以被另一个合约调用)

External 使用起来更便宜,因为它使用calldata操作码,而 public 需要将所有参数复制到内存。

Privateinternal更简单:private意味着该函数只能从合约内部调用,同时internal证明了更宽松的限制,允许从父合约继承的合约使用该函数。

也就是说,保留你的功能private ,除非internal 需要外部交互。

代表调用Delegatecall

solidity docs解释

“Delegatecall 与消息调用相同,区别在于,目标地址的代码在调用合约的上下文中执行msg.sender并且msg.value不会更改它们的值。

这意味着合约可以在运行时从不同的地址动态加载代码。存储、当前地址和余额仍然是调用合约,只是代码取自被调用地址。”

这个低级函数非常有用,它是实现库和模块化代码的支柱。然而,它打开了漏洞的大门。

在下面的示例中,攻击者可以调用合约 Delegate 的公共函数pwn,并且由于调用是在上下文中的Delegation,他们可以声明合约的所有权。

Parity hack 涉及不安全的可见性修饰符和滥用delegate调用与 abritrary 数据的组合。易受攻击的合约的功能已实现delegatecall,另一个合约中可以修改所有权的功能被公开。这使得攻击者可以制作该msg.data字段来调用易受攻击的函数。

至于msg.data字段中包含的内容,那就是您要调用的函数的签名。sha3 (alias for keccak256)这里的签名是指函数原型散列的前 8 个字节。

在这种情况下:

web3.sha3("pwn()").slice(0, 10) --> 0xdd365b8b
如果函数接受参数,pwn(uint256 x):
web3.sha3("pwn(uint256)")。切片(0,10)-> 0x35f4581b

3. 重入(TheDAO hack)

Solidity 的call 函数在调用时value转发它收到的所有gas。在下面的代码段中,在实际减少发件人的余额之前,调用就已经进行了。这打开了一个漏洞,当 TheDAO hack 发生时,reddit评论中对此进行了很好的描述:

“简单来说,这就像银行出纳员在给你所有你要求的钱之前不会改变你的余额。“我可以提取 500 美元吗?等等,在那之前,我可以提取 500 美元吗?”

等等。设计的智能合约只在开始时检查你有没有 500 美元,就检查一次,还允许被打断。”

解决方法是在进行价值转移之前减少发件人的余额。对于使用过并行编程的人来说,另一种解决方案是使用mutexes

目前,使用msg.sender.transfer(_value) 是最佳实践。如果你真的需要使用send使用require(msg.sender.send(_value));

第 一 部分到此结束。第二部分将更新在老雅痞公众号上,我们将讨论一些鲜为人知的漏洞利用、应该添加到工作流程中的工具以及智能合约安全的未来。



往期学习回顾:

开篇第一课:什么是 DAO?

「DAO」剪刀标签Scissor Labels:关于叙述争夺、激励以及如何造成分裂

「DAO」为什么去中心化很重要

DAO 的定义:大局观

DAO《术语指南》:智能合约、自治代理、去中心化应用等

所有权经济:加密和消费软件的下一个前沿(已经是了)

NFT 让互联网赋予用户所有权

NFT 初学者指南——它们是什么,为什么它们很有趣

NFT词典:你需要知道的所有术语和定义

NFT的标准:ERC721、ERC1155和ERC-998

NFT的元数据:链上与链下,存储解决方案

NFT艺术超棒的 8 个原因——以及数字创意新经济

NFT 将如何为激情经济提供动力;关于Solana区块链和NFT,你需要知道的一切

加密货币将改变价值,NFT 将改变社会

策展人角色的作用,NFT 在哪里捕获价值?

NFT的2018-2019:回到建设

区块链到底是个啥?

区块链和比特币到底是怎么工作的?

区块链:硬分叉、软分叉、默认和强制

区块链经济:机构加密经济学初学者指南

「共识」以太坊是如何运作的?上

「共识」以太坊是如何运作的?下

「V神亲笔」权益证明设计理念

加密代币:开放网络设计的突破

比特币和以太坊的去中心化对比

胖协议Fat Protocols的作用

什么是闪电网络Lightning Network,它如何帮助比特币扩展?

【声明】内容源于网络
0
0
FastDaily
日更新闻
内容 2683
粉丝 0
FastDaily 日更新闻
总阅读593
粉丝0
内容2.7k