美文网首页合约安全
合约安全:使用外部合约隐藏恶意代码

合约安全:使用外部合约隐藏恶意代码

作者: 梁帆 | 来源:发表于2022-12-07 17:12 被阅读0次

    本文说的其实不算是漏洞,更像是一个项目方的后门,也是需要注意的,尤其是使用者需要警惕的。
    这个案例告诉我们:开源给你看的合约代码,未必是实际执行的代码。

    一、案例说明

    合约开发者暴露给外部的合约如下:

    contract Foo {
        Bar bar;
    
        constructor(address _bar) {
            bar = Bar(_bar);
        }
    
        function callBar() public {
            bar.log();
        }
    }
    
    contract Bar {
        event Log(string message);
    
        function log() public {
            emit Log("Bar was called");
        }
    }
    

    这个Foo合约是给使用者操作的合约,如果我们单看这两个合约,似乎没看到什么问题。但是请注意这里的构造函数,初始化了Bar合约的地址,但是我们并不是非得传入Bar合约的地址,我们可以传入另外一个钓鱼合约的地址,如下:

    contract Mal {
        event Log(string message);
    
        function log() public {
            emit Log("Mal was called");
        }
    }
    

    这个Mal合约,并没有暴露给外界,而且有和Bar合约一样的方法log,这个合约部署完成后,Foo合约用Mal合约地址进行初始化,这样使用者在调用callBar的时候,实际上调用的是Mal合约上的log方法。

    这种后门是比较隐蔽的,如果没有看到它每一步的部署,很可能会被项目方骗。

    二、预防方法

    • 在构造函数中初始化新的合约
    • 公开外部合同的地址,以便审查外部合同的代码
    contract Foo {
        Bar public bar;
    
        constructor() public {
            bar = new Bar();
        }
    
        function callBar() public {
            bar.log();
        }
    }
    

    可以看到改进后,bar的可见性从默认的internal变成了public;此外,constructor也不用合约地址初始化了,而是在里面new了Bar合约,这样就保证bar变量确实是Bar合约的地址,自行证明了合约的清白性。

    相关文章

      网友评论

        本文标题:合约安全:使用外部合约隐藏恶意代码

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