美文网首页以太坊Solidity智能合约开发
智能合约编程/Dapp漏洞 -- 交易授权/Tx.Origin

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

作者: 末座少年 | 来源:发表于2019-03-07 20:25 被阅读0次

    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()publicpayable{} // collect ether  functionwithdrawAll(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.

    相关文章

      网友评论

        本文标题:智能合约编程/Dapp漏洞 -- 交易授权/Tx.Origin

        本文链接:https://www.haomeiwen.com/subject/vvnhpqtx.html