一、合约安全
1、整数溢出
https://www.thinkingsolidity.com/shi-yan-1-6/
2、交易依赖攻击
区块链系统的交易的是需要矿工打包确认的,而整个过程有一定的延迟性,攻 击者可以利用这样的特性进行攻击。
pragma solidity^0.8.0;
contract orderAttack {
uint256 public bonus;
address owner;
address winer;
constructor(address _win) public payable {
bonus = msg.value;
owner = msg.sender;
winer = _win;
}
modifier onlyOnwer() {
require(msg.sender == owner);
_;
}
function getBonus() payable public {
require(msg.sender == winer);
payable(msg.sender).transfer(bonus);
}
function setBonus(uint256 _bonus) public onlyOnwer {
bonus = _bonus;
}
}
合约发布者可以在该交易没有被确认的时候,立即用更高的 gasprice 价格去执行 setBonus 函数,将金额减小甚至将其变为 0。由于更 高的 gas 费用,矿工通常会将 setBonus 交易优先打包,如果 setBonus 交易先被 执行,那么胜出者将拿不到本该属于他的收益。这也就是交易顺序依赖攻击,顾名 思义,也就是利用交易执行先后顺序导致的结果差异进行攻击。
3、 时间戳依赖攻击
只要矿工人为作恶,他们是可以改变时间戳的(一定程度上,矿 工可以设置未来的时间戳作为块时间戳,但这个时间戳要比较接近,并且能够被区块链所接受),因此这样的限定条件对矿工来说可能会形同虚设,这也就是时间戳依赖的最大问题所在。
4、 算法缺陷
由于智能合约缺乏统一规范,而智能合约的开发者水平又参差不齐,导致智能合约在应用时经常出现算法方面的缺陷。例如前文介绍的时间戳依赖和整数溢出也算是一种算法缺陷。
5、 底层函数误用【264页】
在智能合约开发过程中,为了业务逻辑的实现,有时需要跨合约调用。跨合约 调用因为涉及到与合约外部的合约打交道,这往往成为黑客攻击的手段。合约编写 时,如果误用了底层函数,很可能送给黑客攻击的机会。
6、 权限验证错误
权限验证错误也是智能合约开发过程中经常容易出现的错误。在这类错误中, 有些是开发者疏忽而导致权限控制形同虚设。例如下面的代码:
contract changeOwner {
address owner;//管理员
constructor() public {
owner = msg.sender;
}
function updateOwner(address newOwner) public {
owner = newOwner;
} //其他代码
}
该合约中设置了一个管理员地址,也希望在某些时刻更够替换管理员。然而, 在使用替换管理员的函数 updateOwner 时,并没有进行权限验证,此时任何一个 账户都可以调用该函数将管理员地址更改,并取得对合约的管理权。
除了这样的低级失误,也有开发者会错误的使用tx.origin,tx.origin 是一个固 定变量,它代表的永远是合约最初发起的调用者,它不会像 msg.sender 那样会随- 268 - 着外部合约调用而发生改变。因为 tx.origin 永远代表调用者本身,所以有些开发者 会使用 require(owner == tx.origin)这样的条件验证。例如下面的代码:
contract changeOwner {
address owner;//管理员
constructor() public {
owner = msg.sender;
}
function updateOwner(address newOwner) public {
require(tx.origin == owner);
owner = newOwner;
} // 其它代码
}
这个 updateOwner 也有可能会遭到黑客的攻击,黑客可以诱使该合约的管理员调用黑客的攻击合约,黑客的攻击合约通过 fallback 函数调用该合约的updateOwner 方法,由于 tx.origin 始终代表合约的最初调用者,因此该权限验证将被黑客绕过并取得该合约的控制权。
二、共识安全
区块链作为一个分布式系统,必然需要节点间达成共识,共识问题也成为区块 链系统可能被攻击的点。
1、51%攻击
在 POS 共识中,51%攻击依靠的是筹码(财力),攻击方只要能够拥有网络内超过 51% 的筹码,就可以直接影响区块链网络的出块。
2、女巫攻击
在区块链网络中,尤其是公有链网络,攻击者可以伪造多个身份加入网络。当攻击者伪造了一定数量的节点 和身份后,便有机会威胁到区块链网络。例如,当一些查询请求发送到这些节点时,攻击者可以干扰查询,返回错误结果,甚至拒绝回复,通过这样的方式降低区块链 网络节点的查询效率。除此之外,女巫节点还可以在网络中传输非授权文件、破坏 网络中文件共享等攻击手段。
3、双花攻击
所谓双花,简单理解就是一笔资金花两次或多次。双花攻击是虚拟数字货币特 有的攻击方式,在法币现金系统下是不存在双花攻击的,人们一手交钱一手交货的 行为并不会出现双花。
由于区块链是链式结构,当一个交易 被主链确认后,后一个交易也注定是非法的。因此,若要双花攻击成功,区块链一 定会出现分叉,而若想分叉成功攻击者必须拥有足够的算力。
4、定向攻击【272页】
定向攻击,也被称为高级可持续性威胁(英语:advanced persistent threat, 缩写:APT),是指隐匿而持久的电脑入侵过程,通常由某些人员精心策划,针对特 定的目标。其通常是出于商业或政治动机,针对特定组织或国家,并要求在长时间 内保持高隐蔽性。
5、长程攻击【272页】
所谓长程攻击,其实是指攻击者在数分钟内快速制造一条长于主链的链,并且 被网络中的节点所接受。长程攻击理论上能够成功的原因在于,在 PoS 协议下,区 块的产生者需要质押代币。当区块产生后,出块者可以收回曾经质押的代币,曾经 计算区块的密钥也就没有价值了。攻击者可以以较低的价格收购之前的密钥,这样 攻击者就有机会快速的制造一条更长的伪链。
三、网络安全【273页】
1、分布式拒绝服务攻击(DDoS)
传统的 DDoS 攻击要分为两步:
第一步为准备阶段,黑客要利用病毒、木马、 缓冲区溢出等方式入侵大量主机,形成僵尸网络;
第二步是利用僵尸网络发起 DDos 攻击。不同于传统的中心化系统,针对区块链系统的 DDoS 攻击又可以分为两类: 主动攻击和被动攻击。
四、区块链隐私保护【280页】
1、盲签名
盲签名的使用意义主要用于隐私保护,若发起交易方使用盲签名技术发起交易, 将使整个交易不可被追踪。盲签名的关键点在于数据盲化技术,签名者签名时看到 的是盲化后数据,脱盲后签名者本人无法将签名和盲化数据联系起来。
2、群签名
群签名方案是一种类似于数字签名的密码原语,其目的在于允许用户代表群签 名消息,并在该群内保持匿名。也就是说,看到签名的人可以用公钥验证该消息是 由该群成员发送的,但不知道是哪一个。同时,群成员不能滥用这种匿名行为,因 为群管理员可以通过使用秘密信息(密钥)来消除(恶意)用户的匿名性。
3、环签名
环签名是一种数字签名,可由一组用户中的任何成员执行,每个用户都拥有密钥。因此,用环签名签名的消息由特定人群中的某个人背书。
4、零知识证明
零知识证明是指证明者(prover)能够在不向验证者(verifier)提供任何有用的 信息的情况下,使验证者(verifier)相信某个论断是正确的。
零知识证明实际上是基于概率的一种验证方式,验证者若想验证证明者是否真实知道某个问题的答案,验证者需要随机的向证明者提出问题,如果证明者每次都能回答正确,当验证次数足够多时,则可以认为证明者大概率知道问题的真实答案。