【入門編】 WAFにおけるSQLインジェクション検知の誤検知(False Positive)抑制チューニング – インフラ・ネットワーク & クラウドセキュリティ防御ガイド

こんにちは!インフラやセキュリティの世界へようこそ。
初めてセキュリティの部署に配属されたり、開発者として「WAF(Webアプリケーションファイアウォール)」の管理を任されたりすると、最初は専門用語ばかりで圧倒されてしまいますよね。「何だか難しそう…」と不安になるかもしれませんが、一歩ずつ一緒に紐解いていけば大丈夫です!

今日は、WAFの現場で避けては通れない、そして多くのエンジニアが頭を悩ませる「SQLインジェクションの誤検知(False Positive)抑制チューニング」についてお話しします。

現場のリアルな泥臭いノウハウを交えながら、できるだけ分かりやすく解説していきますね。

—

1. 家の防犯に例えるWAFと「SQLインジェクション」

まずは、WAFや攻撃の仕組みを身近な例でイメージしてみましょう。

皆さんのWebサイトは、いわば「大切な品物を保管しているお店のショーウィンドウ」です。そして、インターネットの向こう側からやってくるお客さん(時には悪意ある人)がアクセスしてきます。

攻撃の正体:言葉巧みな泥棒

「SQLインジェクション」というのは、泥棒がお店の自動ドアの隙間から特別な合言葉(不正なプログラムの断片)を差し入れて、店の奥にある「顧客情報が詰まった金庫の鍵」を無理やり開けさせてしまう手口のことです。
例えば、検索窓に OR 1=1 のような特別な文字列を入力して、本来は見えてはいけないデータをごっそり盗み出す、という古典的かつ強力な攻撃です。

WAFの役割:超有能だけど少し心配性のガードマン

この泥棒を防ぐために配置されるのが、WAF(Webアプリケーションファイアウォール)です。
WAFは、お店の入り口に立つ「超有能だけど、ちょっと心配性なガードマン」だと思ってください。

ガードマンは、お客さんが入力した言葉の中に「怪しいキーワード(SELECT や DROP、あるいは記号の ' など)」が入っていないかを厳しくチェックします。怪しい言葉を見つけると、「おい、泥棒だな!」とピシャリとお店に入れないように遮断(ブロック)してくれます。これがWAFの基本動作です。

—

2. なぜ「誤検知(False Positive)」が起きるのか?

ここで問題が発生します。心配性のガードマン(WAF)が、真面目なお客さんまで「泥棒だ!」と勘違いして追い返してしまう現象、これが「誤検知(False Positive)」です。

例えば、あるお客さんがお問い合わせフォームやプロフィール欄に、こんな文章を書いたとします。

> 「私はオーストラリアに住んでいます。特技はゴルフです。」

お気づきでしょうか?
「オストラリア」や「ゴルフ」という言葉の中に、偶然にも OR や GO といった、SQL(データベースの言語)でよく使われる英単語のパーツが含まれてしまっています。

従来の単純なルール(正規表現ベースのルール)で動くWAFは、「おいおい、この文章の中にデータベースを操作する怪しい単語が入っているぞ!」と勘違いしてしまい、「不正アクセス検知!」として正当なユーザーのリクエストをブロックしてしまうのです。

せっかくの顧客を追い返してしまうわけですから、これはビジネスにおいて大問題ですよね。

—

3. 現場で使える!誤検知をスマートに防ぐ3つのアプローチ

では、この心配性のガードマン(WAF)をどうやって賢く調教(チューニング)すればよいのでしょうか?
現場で私たちがよく使う、安全かつ実践的な3つのステップをご紹介します。

アプローチ1:丸裸で検査するな!「リクエストボディの解析設定」を正しく行う

WAFが誤検知を起こす最大の原因の一つは、ブラウザから送られてきたデータ(リクエストボディ)を、ただの「意味不明な文字の羅列」として雑にスキャンしている点にあります。

例えば、データが application/json や application/x-www-form-urlencoded といった形式で届いている場合、WAFに対して「これはこういう構造のデータですよ」と正しく教えてあげる必要があります。

近年のクラウド型WAFや商用WAFでは、Content-Type(データの形式)を正しくパース(解析)し、JSONの「キー(項目名)」なのか「バリュー(中身)」なのかを識別する機能があります。中身のテキスト部分だけに厳密にルールを適用するよう、設定を見直しましょう。

アプローチ2:雑な全体除外は厳禁!「個別ルールの例外設定」を使う

「誤検知が多いから、このSQLインジェクションのチェックルール自体を全部オフにしちゃおう!」
……これは絶対にやってはいけない禁手です。家の鍵を全開にして出かけるようなもので、本物の泥棒に入られてしまいます。

正しくは、「特定のURLや、特定のパラメータでのみ、そのルールを免除する(例外指定する)」というピンポイントな設定を行います。

例えば、ブログの投稿記事を受け取る /api/posts というAPIの content(本文)パラメータにおいてのみ、特定の正規表現ルールをバイパスさせる設定例を見てみましょう。(※概念的な設定イメージです)

{
  "rule_id": "WAF-SQLI-001",
  "action": "block",
  "exceptions": [
    {
      "path": "/api/posts",
      "parameter": "content",
      "reason": "ブログ本文中の自然言語による誤検知を抑制するため"
    }
  ]
}

このように、「どこで」「どの項目で」誤検知が起きたのかを特定し、最小限の範囲だけ除外するのがプロの技です。

アプローチ3:アプリケーション側での「正しいエスケープ処理」

WAFのチューニングだけに頼るのも実は危険です。根本的な安全は、Webアプリケーション(プログラム)側で担保しなければなりません。

例えば、PHPでデータベースに値を保存する際、生のリクエストデータをそのままSQL文に組み込んでいないでしょうか?
以下のように、「プリペアドーステートメント(プレースホルダー)」を必ず使用してください。

【悪い例】(SQLインジェクションの危険があり、WAFの検知にもひっかかりやすい)

// ユーザーからの入力をそのままSQLに結合している(絶対にNG!)
$sql = "SELECT * FROM users WHERE name = '" . $_POST['user_name'] . "'";
$db->query($sql);

【良い例】(安全で、WAFへの依存度も下げられる)

// プレースホルダーを使い、入力値が「ただの文字列」として安全に扱われるようにする
$stmt = $db->prepare("SELECT * FROM users WHERE name = ?");
$stmt->execute([$_POST['user_name']]);
$user = $stmt->fetch();

アプリケーション側がこのように堅牢に作られてい万が一WAFのルールをすり抜けるような入力があっても、データベース側で安全に弾くことができます。「多層防御(アプリとWAFの両輪で守る)」がセキュリティの基本中の基本です。

—

4. チューニング運用の黄金律:ログを愛せよ

最後に、運用時の心構えをお伝えします。

WAFのチューニング作業は、一度設定して終わりではありません。新しい機能がリリースされたり、ユーザーの書き方のトレンドが変わったりすると、また別の誤検知が顔を出します。

現場のエンジニアとして大切なのは、「WAFのブロックログ(検知ログ)を毎日定点観測すること」です。
「本当にこれは攻撃だったのか? それとも大切なお客さんのリクエストだったのか?」
ログを丹念に読み解き、開発チームとインフラチームが密にコミュニケーションを取りながらルールをブラッシュアップしていく。この地道な泥臭い作業こそが、強固なシステムを作り上げます。

最初は難しく感じるかもしれませんが、一つずつログを分析し、誤検知を美しく解消できたときの達成感は格別です。
一歩ずつ、確実にスキルを積み上げていきましょう!応援しています!

コメント

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