脆弱性: タイムスタンプの依存性 (Vulnerability: Timestamp Dependence)

説明:

Ethereum のスマートコントラクトは、オークション、くじ、トークンの権利確定など、時間に敏感な機能において block.timestamp に依存することがよくあります。しかし、block.timestamp は完全に不変というわけではありません。ブロックを採掘するマイナーによって、Ethereum プロトコルの実装によると約 15 秒の範囲内でわずかに調整できるためです。このため、マイナーがタイムスタンプを操作して有利にできる脆弱性が生じます。たとえば、分散型オークションでは、入札者であるマイナーがタイムスタンプを改変して、自分が最高入札者になったときにオークションを早期終了させ、不当に落札できてしまいます。

事例:

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

contract DiceRoll {
    uint256 public lastBlockTime;

    constructor() payable {}

    function rollDice() external payable {
        require(msg.value == 5 ether, "Must send 5 ether to play"); // Player must send 5 ether to play
        require(block.timestamp != lastBlockTime, "Only 1 transaction per block allowed"); // Ensures only 1 transaction per block

        lastBlockTime = block.timestamp;

        // Player wins if the last digit of the block timestamp is less than 5
        if (block.timestamp % 10 < 5) {
            (bool sent,) = msg.sender.call{value: address(this).balance}("");
            require(sent, "Failed to send Ether");
        }
    }
}

影響:

  • 時間指定実行など、重要な操作にブロックタイムスタンプを使用するスマートコントラクトは操作されやすくなります。攻撃者はタイムスタンプを改変し、機能を早期あるいは遅延させてトリガーし、意図した結果を妨害できます。これにより、報酬の発行が早すぎたり、必要な更新が延期されるなどの問題が発生し、コントラクトの運用が不安定になる可能性があります。

  • ブロックタイムスタンプを変更することで、攻撃者はコントラクト内の時間ベースのメカニズムを悪用できます。たとえば、くじゲームでは、攻撃者は特定の条件に合うようにタイムスタンプを調整し、当選の可能性を高めることができます。さらに、機能を繰り返し連続して実行し、コントラクトのリソースを枯渇させたり、不当な利益を獲得する可能性があります。

  • タイムスタンプの操作は、攻撃者が他者よりも戦略的に優位なタイミングでトランザクションを実行するフロントランニングを容易にする可能性があります。コントロールされたタイムスタンプによって影響を受けるこの予測可能性は、金融のコンテキストでは特に有害です。そのような行為は他の参加者に多大な損失をもたらす一方で、攻撃者に不当な利益を提供する可能性があります。

対策:

  • タイムスタンプ操作のリスクを軽減し、スマートコントラクトの正確性とセキュリティを向上させるには、信頼できる外部タイムソースまたは複数のタイムソースを使用することをお勧めします。このアプローチはより信頼性の高いタイミングを確保するのに役立ちます。

  • block.timestamp を使用する必要がある場合は、タイムバッファを追加することを検討してください。たとえば、block.timestamp がオークション終了時刻に 1 分を加えた時間よりも大きい場合にのみオークションが終了するというルールを設定できます。このような猶予時間を設けることで、マイナーが終了時刻を操作することが難しくなり、参加者にとってより公平な結果を提供できます。

Last updated