我正在努力理解以下内容的作用:
withdraw.pendingReturns[msg.sender]=0;
在检测拒绝服务(DoS)漏洞时。下面的论文VeriSolid说:
withdraw.pendingReturnsmsg.sender=0;最终将发生在withdraw.msg.sender.transfer(数量)之后;
这如何帮助我们检测DoS漏洞,因为在“传输”之后,我们无法执行任何操作,因此该技术如何帮助确定DoS漏洞。但是,在以下代码中,msg.sender.amount= 0;是在传输之前完成的,这与本文中的不同:
function withdraw() public {
if(withdrawals[msg.sender].amount > 0
uint amount = withdrawals[msg.sender].amount;
withdrawals[msg.sender].amount = 0;
msg.sender.transfer(amount);
}
}
我们可以使用:
withdrawals[msg.sender].amount = 0;
用于确定DoS漏洞的“传输”之后?
祖尔菲。
发布于 2020-12-29 20:11:36
在我看来,这篇论文措辞拙劣,具有误导性。无可否认,我只浏览了以下声明和附近地区。
上面的模板表示安全属性类型。一个典型的漏洞是货币提取函数(例如转移)允许攻击者在更新余额之前再次提取货币。
首先,我认为我应该消除一些因滥用共同术语而产生的混乱。所描述的攻击不是“拒绝服务”。是“重新入场”前者通常意味着以某种方式拒绝其他用户的访问,例如破坏。后者是一种使合同以一种非预期的方式(由创建者)行为的方法,例如发送比请求者有权得到的更多的钱。
我们可以使用:在“传输”之后的
withdrawals[msg.sender].amount = 0;
最好的做法是使用“检查、效果、交互”模式,它基本上意味着验证,乐观地设置状态,然后与其他契约和地址交互。
您这样做的原因是为了确保在另一个合同接收到流控制之前,合同处于与所考虑的一切保持一致的状态。在易受攻击的配置中,敌对契约可以回拨到原始契约,在那里它会发现会计还没有发生。在最简单的攻击概念中,他们可以再次取钱。
攻击之所以有效,是因为接收契约(攻击者)有一个回退函数,在收到资金时运行,并且可以编码来攻击天真的受害者。
为了保护自己,受害者首先要把自己的房子整理好,并进行会计核算,就好像下一步的成功转让是可以保证的。这样,攻击者将看到他们的权利已经减少,他们不能再提取同样的钱。如果会计是在转账后进行的,那么它们的余额每次都将保持不变,这可能会欺骗受害者释放更多的资金。
当合同在失败的转移后恢复(通常是正确的事情),这就颠倒了先前执行的乐观会计,因此您可以安全地使用违反直觉的事件顺序。
有一个被称为气体津贴的部分重新进入守卫,但当检查、效果、相互作用可以宗教地遵循时,完全依赖它是不好的做法。
希望能帮上忙。
https://ethereum.stackexchange.com/questions/91687
复制相似问题