【実務・中級編】 WAFにおけるSQLインジェクションおよびXSSルールのチューニング – 暗号理論・認証基盤 & エンドポイントセキュリティ防御ガイド

現場のエンジニア諸君、今日も泥臭い戦いご苦労様。

セキュリティの教科書には「暗号化せよ」「入力をバリデーションせよ」としか書かれていないが、現実はそんなに甘くない。WAFのマネージドルールをONにした瞬間に正規のトラフィックまで遮断され、深夜の緊急会議で「とりあえずルールをオフにしてくれ」と叫んだ経験、一度はあるだろう。

今日は、暗号理論という「盾の基盤」を理解した上で、WAFという「最前線の防壁」をどう調整し、実務で使い倒すかについて、現場の知見を叩き込む。

—

1. 暗号の使い分け:原理を知らねば「鍵」は守れない

暗号化の基本だが、AES(共通鍵)とRSA/ECC(公開鍵)の使い分けを誤ると、インフラのパフォーマンスと強度は一瞬で崩壊する。

  • AES(共通鍵暗号): 高速だが、鍵配送が地獄。通信の暗号化(TLSのペイロード部)や、DBの個人情報保管に使う。鍵管理にはAWS KMSなどのHSM(ハードウェアセキュリティモジュール)が必須だ。
  • RSA/ECC(公開鍵暗号): 低速だが、安全な鍵共有ができる。TLSのハンドシェイクやデジタル署名に使う。最近はRSA 2048bitより、同等の強度で計算量が軽く、鍵長が短いECC(楕円曲線暗号)を選ぶのが定石だ。

現場の教訓: DBカラムの暗号化にRSAを使うな。AES-256-GCMを採用し、鍵のローテーション戦略を設計しろ。

—

2. WAFの「誤検知」を恐れるな、制御せよ

AWS WAFやGoogle Cloud Armorのマネージドルールは「魔法の杖」ではない。SQLインジェクションやXSSのパターンマッチングは、往々にして「特殊な入力」を攻撃と誤認する。

誤検知(False Positive)を封じ込める除外ルール

ルールを全部OFFにするのは論外だ。特定のURIパスやパラメータに対して、ルールを「カウントモード」にするか、除外設定を適用する。

例:特定の管理画面のみSQLiルールを緩める設定(JSON形式)

{
  "Name": "Exclude-SQLi-for-Admin-Page",
  "Statement": {
    "AndStatement": {
      "Statements": [
        { "LabelMatchStatement": { "Scope": "LABEL", "Key": "awswaf:managed:aws:sql-database:SQLi_QueryArguments" } },
        { "ByteMatchStatement": { "FieldToMatch": { "UriPath": {} }, "SearchString": "/admin/api/v1/query" } }
      ]
    }
  },
  "Action": { "Allow": {} }
}

—

3. 実践:インジェクションを「無効化」する実装

WAFはあくまで「最後の砦」。アプリケーション側で脆弱性を潰していなければ、WAFの裏をかかれる。

SQLインジェクションを防ぐ(PHP / PDO)

「文字列連結」でSQLを作るのは、泥酔状態で地雷原を歩くのと同じだ。必ずプリペアドステートメントを使え。

// 悪い例: $sql = "SELECT * FROM users WHERE id = " . $_GET['id'];
// 良い例: プレースホルダーを使用する
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id');
$stmt->execute(['id' => $_GET['id']]); // PDOが自動でエスケープ処理を行う
$user = $stmt->fetch();

XSSを防ぐ(JavaScript)

innerHTML は禁句だ。ブラウザが解釈する文字列の中にユーザー入力を混入させないことが鉄則。

// 悪い例: document.getElementById('output').innerHTML = userInput;
// 良い例: .textContent を使い、ブラウザに「文字列として」扱わせる
const userInput = new URLSearchParams(window.location.search).get('name');
const outputElement = document.getElementById('output');

if (userInput) {
    // スクリプトタグが含まれていても、純粋なテキストとして描画される
    outputElement.textContent = userInput;
}

—

4. 現場のプロが教える「インシデントハンドリングの極意」

WAFを調整する際、以下のステップを徹底してほしい。

1. ログを疑え: CloudWatch LogsやStackdriverで、ブロックされたリクエストをJSONで吐き出せ。「なぜブロックされたか」のラベル(SQLi_QueryArgumentsなど)を特定しろ。
2. 正規表現の闇: 複雑すぎる正規表現をWAFに書くな。それは攻撃者に「どこまでなら回避できるか」のヒントを与えることになる。
3. バリデーションは多層で:

  • WAF層: 大まかな攻撃シグネチャを弾く。
  • アプリ層: 型(数値のみ、メール形式など)を厳格にチェックする。
  • DB層: 権限を最小限にし、不要な権限を与えない。

最後に:
セキュリティとは「100%防ぐ」ことではなく、「攻撃のコストを極限まで引き上げ、攻撃者に諦めさせる」ことだ。完璧な城壁を作ろうとして、出入口を塞いで運用を止めるな。設計の段階で脆弱性を排除し、WAFはあくまで「運用しながら叩く」ための補助輪として使いこなせ。

次回のログ解析で、お前たちがスマートに脆弱性を封じ込んでいることを期待している。健闘を祈る。

コメント

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