tx.origin的穿透性和攻击性 / 学习智能合约#19

in STEEM CN/中文4 years ago

origin.jpg

如果只是简单地逻辑实现,那么就应该只用msg.sender就好啰。但是真实情况往往是你需要把逻辑划分成不同的合约来实现,再通过它们之间的相互调用来实现复杂的逻辑。这就好比不同的类之间要相互交流一样。

如上图所示,用户D通过合约B调用合约接口来调用合约A中的函数,这时tx.origin的穿透性就体现出来了。msg.sender只能得到直接调用它的地址(即合约B),得不到用户D的身份,只有tx.origin才能得到!所以,从这里可能看到,tx.origin具有的穿透的访问性。

利用tx.origin的穿透性会产生一定的钓鱼攻击,如下面所示:

pragma solidity >=0.4.22 <0.7.0;

contract UserWallet {
    address owner;

    constructor() public payable {
        owner = msg.sender;
    }

    function transferTo(address payable _to, uint amount) public {
        require(tx.origin == owner);  //tx.origin作验证会有漏洞
        _to.transfer(amount);
    }
}

require(tx.origin == owner);用它用验证时有一定的漏洞,因为任何人都可以创建一个合约B来试图调用这个合约中的transferTo方法来攻陷你的钱包!

如果你已经熟悉了tx.origin的这点特性,倒也不用谈虎色变,它的特性还是给了我们相互调用合约的便利性,使得我们设计的合约复杂度得以提高,能做的事更多。

Coin Marketplace

STEEM 0.21
TRX 0.20
JST 0.035
BTC 91178.33
ETH 3192.43
USDT 1.00
SBD 2.96