外部契約で悪意のあるコードを隠す

脆弱性

Solidityでは、アドレスのコントラクトがキャストされているものでなくても、任意のアドレスを特定のコントラクトにキャストできます。

これを悪用して、悪意のあるコードを隠すことができます。方法を見てみましょう。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

/*
Let's say Alice can see the code of Foo and Bar but not Mal.
It is obvious to Alice that Foo.callBar() executes the code inside Bar.log().
However Eve deploys Foo with the address of Mal, so that calling Foo.callBar()
will actually execute the code at Mal.
*/

/*
1. Eve deploys Mal
2. Eve deploys Foo with the address of Mal
3. Alice calls Foo.callBar() after reading the code and judging that it is
   safe to call.
4. Although Alice expected Bar.log() to be execute, Mal.log() was executed.
*/

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");
    }
}

// This code is hidden in a separate file
contract Mal {
    event Log(string message);

    // function () external {
    //     emit Log("Mal was called");
    // }

    // Actually we can execute the same exploit even if this function does
    // not exist by using the fallback
    function log() public {
        emit Log("Mal was called");
    }
}

予防技術

  • コンストラクター内で新しいコントラクトを初期化します
  • public 外部契約のコードを確認できるように、外部契約のアドレスを 作成します
Bar public bar;

constructor() public {
    bar = new Bar();
}

Remixを試してみてください 

おすすめ

転載: blog.csdn.net/yanning1314/article/details/122824503