【入門編】 タイマー・タイムスタンプ依存の脆弱性 – IoT・OT(制御システム) & ブロックチェーンセキュリティ防御ガイド

こんにちは!セキュリティの世界へようこそ。
普段、家の鍵をかけるとき、あなたは時計を見て「今、18時00分だから鍵をかけよう」と決めますよね?でも、もしその時計が「泥棒の手元で自由に動かせる時計」だったらどうなるでしょうか?

今日は、スマートコントラクトの世界で多くの初心者が陥る罠、「block.timestamp(ブロックのタイムスタンプ)依存の脆弱性」について、一緒に紐解いていきましょう。

—

1. 泥棒が「時間」を操る? タイムスタンプの仕組み

スマートコントラクトの世界では、ブロックチェーンという巨大な帳簿に取引を記録していきます。このとき、それぞれの記録には「いつ行われたか」というタイムスタンプが刻まれます。

プログラムを書くとき、私たちはつい block.timestamp という命令を使って、「今の時間」を取得したくなります。「1日1回だけ報酬がもらえるボタン」を作るとき、この機能は非常に便利に見えますよね。

しかし、ここに大きな落とし穴があります。実は、このタイムスタンプを決めているのは、ブロックチェーンを動かしている「マイナー(採掘者)」たちなのです。

身近な例え話

想像してみてください。あなたがマンションの管理人で、「夜の20時以降はエントランスを施錠する」というルールを作ったとします。ところが、時計の針を自由に変えられる住人(マイナー)がいて、その人が「今はまだ19時59分だ!」と主張して、無理やりエントランスを開けさせようとしたらどうでしょう。

スマートコントラクトの世界では、「ブロックを作る人(マイナー)は、自分の都合の良いように時間を数秒〜数分ずらして記録できる」というルールがあるのです。

—

2. なぜこれが危険なのか?

もし、あなたの作ったコントラクトが「タイムスタンプがちょうど〇〇時になった瞬間に送金する」といった厳密なロジックを持っていたら、攻撃者はその「数秒の誤差」を悪用して、本来もらえるはずのない報酬を横取りしたり、抽選結果を操作したりすることができてしまいます。

「たった数秒のズレでしょ?」と思うかもしれませんが、Web3の世界ではその一瞬が数千万円、数億円の差を生むことだってあるんですよ。

—

3. 安全なコードの書き方:一歩ずつ対策しよう

では、どうすればこの罠を回避できるのでしょうか?
結論から言うと、「厳密な時間管理をタイムスタンプだけに頼らない」ことが大切です。

脆弱なコード例(やってはいけない書き方)

// 警告:これは危ないコードです!
function claimReward() public {
    // タイムスタンプが特定の時間ちょうどを指しているか確認している
    // マイナーが時間を操作して、この条件を無理やり満たす可能性があります
    require(block.timestamp == 1700000000, "まだ時間ではありません");
    
    // 報酬を支払う処理...
}

安全なコード例(こう書き換えましょう!)

もし時間制限を設けたいなら、block.timestamp を絶対的な基準にするのではなく、「許容範囲(バッファ)」を持たせるのが鉄則です。

// 安全なコードの例
function claimReward() public {
    // 「ちょうどその秒」ではなく「その時間を過ぎているか」で判定する
    // これなら数秒の誤差があっても攻撃は成立しにくくなります
    require(block.timestamp >= lastClaimTime + 1 days, "24時間は経過していません");
    
    lastClaimTime = block.timestamp;
    // 報酬を支払う処理...
}

重要なポイント

1. 厳密な秒数に依存しない: == で比較するのではなく、>= を使って「期間が経過したか」を判定しましょう。
2. 外部の信頼できる時計を使う: 本当に厳密な時間が必要な場合は、Chainlink Oracle などの「外部から信頼できる時間データを持ってくる仕組み」を利用するのが、プロの現場では一般的です。

—

4. 最後に:セキュリティは「疑うこと」から始まる

IT担当者や開発者の皆さん、スマートコントラクトにおいて「システムが提供してくれる便利な値」は、往々にして「誰かが操作できる値」であることを覚えておいてください。

「この値は、誰が管理しているものなのか?」
「もしこの値が数秒ズレたら、自分のプログラムはどう動くのか?」

このように一歩立ち止まって考えるだけで、あなたのコードの堅牢性は劇的に向上します。セキュリティは一度学んで終わりではなく、日々の開発の中で「疑い、守り、改善する」の繰り返しです。

次回の記事では、他にも「隠された落とし穴」について深掘りしていきます。一緒に、安全で強固なWeb3の世界を築いていきましょう!

何か分からないことがあれば、いつでも相談してくださいね。一歩ずつ、着実に学んでいきましょう!

コメント

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