【入門編】 DoS攻撃(Denial of Service)のベクトル – IoT・OT(制御システム) & ブロックチェーンセキュリティ防御ガイド

スマートコントラクトが「沈黙」する日:DoS攻撃からあなたのDAppsを守るための防犯術

こんにちは!セキュリティの世界へようこそ。今日は、ブロックチェーンという「デジタルな金庫」を守るための、少し特殊な泥棒の防犯対策についてお話しします。

皆さんは「DoS攻撃」という言葉を聞いたことがありますか?難しく聞こえますが、要するに「お店の入り口に何百人ものサクラを並ばせて、本当のお客さんが入れないようにする嫌がらせ」のことです。ブロックチェーンの世界では、この嫌がらせが、あなたの作った大事なプログラム(スマートコントラクト)を完全に麻痺させてしまうことがあるんです。

今日は、初心者の方でもわかるように、この「サービス停止の罠」をどう回避するか、一緒に見ていきましょう!

—

1. なぜ「金庫」が突然開かなくなるのか?

スマートコントラクトには、現実世界の銀行や金庫にはない、ちょっと特殊なルールがあります。それは「計算するたびに手数料(ガス代)がかかる」という点です。

例えば、あなたが運営しているサービスで、「全員に一斉に報酬を配る」というボタンを作ったとしましょう。これ、一見便利そうですよね?でも、これが泥棒(攻撃者)にとっては格好の餌食になるんです。

泥棒の手口:終わらない計算をさせる

もし、報酬を受け取るユーザーが1人から1,000人に増えたらどうなるでしょう?プログラムが「1人ずつ順番に計算して送金する」という作りだった場合、処理が長すぎて、ブロックチェーンが許容する「1回の処理の上限(ガスリミット)」を超えてしまいます。

結果として、「処理が重すぎて計算が終わらない(ガス切れ)」というエラーが発生し、プログラム全体がエラーで止まってしまうのです。これが、スマートコントラクトにおけるDoS攻撃の正体です。

—

2. 悪い例:プッシュ型決済の罠

まず、やってはいけない「プッシュ型(勝手に配る)」の実装例を見てみましょう。

// 悪い例:全員に一気に配ろうとするコントラクト
function distributeRewards() public {
    // ユーザーリストが長くなると、ここでガス制限を超えて爆発する
    for (uint i = 0; i < users.length; i++) {
        users[i].transfer(rewardAmount); // ここで1人ずつ送金
    }
}

これだと、ユーザーが増えれば増えるほど、誰か一人でも送金に失敗したり、リストが長すぎたりすると、全員分が失敗してしまいますよね。これでは誰も報酬を受け取れません。

—

3. 防御策:プル型決済という「窓口」を作る

では、どうすればいいのでしょうか?答えはシンプルです。「全員に配る」のをやめて、「欲しい人が自分で取りに来る」という「プル型」に変更することです。

これは、家の中に全員分の郵便物を投げ込むのではなく、「郵便局の窓口に来てくれた人だけに手渡す」という仕組みに変えるのと同じです。

// 良い例:プル型(引き出し型)の実装
mapping(address => uint) public pendingWithdrawals;

// ユーザーが自分で引き出す関数
function withdraw() public {
    uint amount = pendingWithdrawals[msg.sender];
    require(amount > 0, "引き出すものがないよ!");

    pendingWithdrawals[msg.sender] = 0; // 二重取り防止のため先に0にする
    payable(msg.sender).transfer(amount);
}

このように実装すれば、どんなにユーザーが増えても、誰か一人が処理を失敗しても、他の人には全く影響がありません。これが、ブロックチェーンにおける最強の防犯対策の一つです。

—

4. セキュリティ担当者からのアドバイス

「プッシュ型」が絶対にダメというわけではありません。しかし、ユーザー数が増えることが予想されるサービスでは、必ず「分割払い」や「各自引き出し」の仕組みを検討してください。

初心者のうちは、以下のチェックリストを心に留めておくだけで、リスクを大幅に減らせます。

  • ループ処理を避ける: for文で配列を回す処理は、将来的に必ずパンクします。
  • 「自分でやってもらう」が正義: 送金や重い処理は、なるべくユーザー個人の操作(withdrawなど)に委ねる。
  • ガス代の計算を意識する: 「これ、1000人で実行したらガス代いくらになるかな?」と想像するクセをつける。

—

最後に:一歩ずつ、強固なシステムへ

セキュリティ対策と聞くと身構えてしまうかもしれませんが、結局のところ、大切なのは「もし全員が同時に使ったらどうなるか?」「もし誰かが意地悪な入力をしてきたらどうなるか?」を想像することです。

最初は難しく感じるかもしれませんが、こうして一つずつ知識を積み上げていけば、あなたは必ず頼りになる開発者になれます。

もしコードを書いている最中に「これって大丈夫かな?」と不安になったら、またいつでもここに戻ってきてくださいね。一緒に安全なWeb3の世界を作っていきましょう!

それでは、今日はこの辺で。安全なコーディングライフを!

コメント

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