なぜ「悪いもの」だけを探すのは無駄なのか?インジェクション攻撃からアプリを守る「ホワイトリスト」の哲学
こんにちは。セキュリティの現場で日々、泥臭いインシデントと向き合っているエンジニアです。
今日は、プログラミングを始めたばかりの方や、セキュリティの「セ」の字も知らないという方に向けて、「インジェクション攻撃」という、Webの世界で最も恐ろしく、かつ最も防ぎやすい攻撃についてお話しします。
「セキュリティ対策=怪しいものをブロックする」と思っていませんか?実は、その考え方こそが、泥棒を招き入れる最大の盲点なんです。
—
1. 「泥棒名簿」を作るという終わりのない戦い
まず、ブラックリスト方式の限界について考えてみましょう。
想像してみてください。あなたは自分の家の玄関に「泥棒リスト」を貼っています。「この顔の奴は入れたらダメだ」と、過去の泥棒の顔写真を全部貼り出すんです。でも、泥棒は常に新しい変装をしますし、あなたの知らない新しい泥棒が毎日生まれていますよね。
システムにおけるブラックリスト方式とは、まさにこれです。
「' OR 1=1 -- という文字列が入ってきたら拒否する」「 があったら削除する」……。
しかし、攻撃者は「あなたの知らない変な記号」や「見たことのない言語の組み合わせ」で、あなたのチェックをすり抜けてきます。「悪いものを探して排除する」というやり方では、一生、泥棒の先回りなんてできません。
2. 「合言葉」を知っている人だけを通す:ホワイトリスト方式
そこで登場するのがホワイトリスト方式です。
これは「誰を入れないか」ではなく、「誰なら入れていいか(何なら受け取っていいか)」だけを決めるという、潔い防犯対策です。
あなたの家の鍵穴が「特定の形の鍵しか受け付けない」のと同じです。どんなに怪しい変装をした人が来ても、その鍵を持っていなければ、そもそも物理的にドアを開けることができません。これこそが、インジェクション攻撃を根絶するための最強の防御術です。
---
3. 実践!プログラムでどう守るのか
では、具体的にどう書くのかを見てみましょう。例えば、ユーザーが「年齢」を入力する場面を想像してください。
ダメな例(ブラックリスト思考)
// 「悪い文字」だけを探そうとするコード
function validateAge(input) {
// 「'」や「;」が入っていたらエラーにするという発想
if (input.includes("'") || input.includes(";")) {
return "不正な入力です";
}
return "OK";
}
これだと、SQLインジェクションの別パターンや、未知の攻撃手法に簡単に突破されてしまいます。
良い例(ホワイトリスト思考)
// 「期待するもの」以外はすべて拒否するコード
function validateAge(input) {
// 1. まずは「数字だけ」であるかを確認(正規表現)
// 2. 「0から120の間」という範囲に収まっているかを確認
const age = Number(input);
// 数字かどうか? かつ、0より大きく120以下か?
if (Number.isInteger(age) && age > 0 && age <= 120) {
return true; // これだけを通す!
}
// それ以外は全部「不正」とみなす
return false;
}
たったこれだけです。「数字以外は入ってこなくていい」とルールを決めてしまえば、攻撃者がどんなに巧妙なSQLコマンドを送り込もうとしても、プログラムは「あ、これ数字じゃないから無視しよう」と弾いてくれます。
---
4. セキュリティは「性悪説」で設計する
開発現場では、「ユーザーがまともな入力をしてくれるはずだ」という性悪説の欠如が一番の脆弱性になります。
皆さんがこれから書くコードでは、以下の3ステップを「おまじない」にしてください。
1. 型を確認する: それは数字ですか?文字ですか?(型チェック)
2. 形式を確認する: メールアドレスの形ですか?郵便番号の桁数は合っていますか?(正規表現)
3. 範囲を確認する: 100円の買い物で、マイナスの個数を入力させたりしていませんか?(範囲チェック)
---
最後に:一歩ずつ積み上げよう
セキュリティは、一度完璧にしたら終わりというものではありません。でも、今日お伝えした「悪いものを弾くのではなく、良いものだけを通す」というホワイトリストの考え方は、皆さんのコードを確実に強くします。
泥棒の顔写真を必死に覚える必要はありません。あなたの家の鍵穴の形を、誰にも真似できないほど正確に定義してあげてください。
最初は面倒に感じるかもしれませんが、それが結果的に、あなた自身と、あなたのサービスを使うユーザーを守る、一番の近道になるはずです。一緒に、安全なコードを書いていきましょう!
コメント