【入門編】 EIP-1271によるスマートコントラクトウォレットの署名検証リスク – IoT・OT(制御システム) & ブロックチェーンセキュリティ防御ガイド

鍵の「形」を盗む泥棒たち:EIP-1271が抱える意外な盲点

みなさん、こんにちは!ITの世界へようこそ。
普段、スマートフォンの認証やWebサイトへのログインで「署名」という言葉を耳にすることはありませんか?

今日は、そんな「デジタルな署名」の世界で、いま最も注目されている「EIP-1271」という仕組みの裏側に潜む、ちょっと怖い「なりすまし」の落とし穴についてお話しします。難しそうに聞こえるかもしれませんが、身近な「家の鍵」に例えながら、一緒に紐解いていきましょう!

—

1. 署名って、実は「身分証明書」のことなんです

私たちが自分のウォレット(暗号資産の財布)から何かを送る時、必ず「秘密鍵」という電子的なハンコを押します。これを「署名」と呼びます。

しかし、最近増えている「スマートコントラクトウォレット」という特殊な財布は、人間ではなく「プログラム」で動いています。このプログラムが「これは私が押したハンコですよ」と証明するために使われるのが EIP-1271 という規格です。

例えるなら、「この屋敷の主人は、AI執事が発行した証明書を持ってくるはずだ。その証明書を執事に見せて確認させれば間違いはない」という取り決めのようなものです。

2. なぜ「なりすまし」が起きるのか?(再帰呼び出しの罠)

さて、ここからが本題です。もし、この「AI執事(スマートコントラクト)」が、うっかり騙されやすい性格だったらどうでしょう?

攻撃者は、わざと「自分自身を呼び出すような複雑な命令」を仕込みます。これを専門用語で「再帰呼び出し」と呼びます。

泥棒の手口:鏡合わせのトリック

泥棒は、家の鍵(署名)を盗むのではなく、「鍵を確認するルールそのもの」を書き換えてしまいます。
1. 攻撃者は、「私の署名は正しいですよね?」と執事に聞きます。
2. 執事が確認しようとした瞬間、攻撃者は「いや、もう一度最初から確認して!」と複雑な命令を送り、執事をパニック(無限ループ)に陥らせます。
3. その隙に、執事が「はい、正しいです!」と言わざるを得ない状況を作り出し、堂々と屋敷(ウォレット)に侵入するのです。

これが、EIP-1271の検証ロジックが甘いときに発生する「なりすましリスク」の正体です。

—

3. 守るための第一歩:コードで見る「防御の仕組み」

では、どうすればこの泥棒を防げるのでしょうか?
ポイントは、「誰から確認の依頼が来ても、必ず決まった手順で冷静にチェックすること」です。

以下は、安全な検証を行うための基本的な考え方を示したコード例です。

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

contract SecureWallet {
    // 署名の有効性を確認するメインの関数
    function isValidSignature(bytes32 _hash, bytes memory _signature) public view returns (bytes4) {
        
        // 1. まず、署名が正しい形式かチェック(ここで無駄な計算をさせない)
        require(_signature.length == 65, "署名の長さが不正です!");

        // 2. 署名者(持ち主)が本当に本人か確認
        address signer = recoverSigner(_hash, _signature);
        
        // 3. 本人であれば、特定の「魔法の合言葉(MagicValue)」を返す
        if (signer == owner) {
            // 0x1626ba7e は「この署名は正しいですよ」と伝えるための合言葉
            return 0x1626ba7e; 
        }

        // 失敗した場合は無効であることを伝える
        return 0xffffffff;
    }
}

ポイント解説

  • 0x1626ba7e: これが「EIP-1271の合言葉」です。これを返さないと、世の中の多くのシステムは「この署名は偽物だ」と判断します。
  • require: これが「門番」です。怪しい入力が来たら、すぐに門を閉じて(処理を中断して)泥棒を追い返します。

—

4. セキュリティリサーチャーからのアドバイス

新人開発者の皆さんに、これだけは覚えておいてほしいことがあります。

「プログラムは、あなたが書いた通りに動くのではなく、あなたが書かなかった例外の時ほど、予期せぬ動きをする」

特にブロックチェーンの世界では、一度公開したルールを後から直すのは非常に困難です。「まあ大丈夫だろう」という油断が、数億円規模の被害を生むこともあります。

私たちができること:

1. 複雑にしない: 検証ロジックは可能な限りシンプルに保ちましょう。
2. 外部を信じない: 他のコントラクトからの呼び出しには、必ず「これは本当に許可された相手か?」というチェックを挟んでください。
3. テストを徹底する: 泥棒になったつもりで、「もし変なデータが来たらどうなる?」という意地悪なテストをたくさん書きましょう。

セキュリティは、一度完成して終わりではありません。家の鍵を毎日確認するように、少しずつ知識をアップデートしていきましょうね。

また次回の記事で、より深い「防御の極意」についてお話ししましょう。それでは、安全な開発ライフを!

コメント

タイトルとURLをコピーしました