目次
「取引先のセキュリティチェックシートに『WAFを導入していますか』という項目があるが、ファイアウォールとは違うのか」「WAFを入れたら問い合わせフォームが403で送れなくなった」「マネージドルールを全部オンにしたが、これで安全と言えるのか」。WAFは"入れれば守られる"と思われがちですが、仕組みを理解せずに導入すると、正規のユーザーを弾きながら本当の攻撃は素通り、という状態になりがちです。
この記事では、WAF(Web Application Firewall)がネットワークファイアウォールやIDSとどう違うのかを整理し、シグネチャとマネージドルールの仕組み、Cloudflare WAF・AWS WAF・ModSecurityの導入パターンの比較、フォーム送信がブロックされる誤検知の調査と例外設定の手順、ログ監視の運用、そしてWAFが代替できないものを解説します。サーバー側のファイアウォール設定とOWASP Top 10の内容は既知として進めます。
WAFとは何か|ファイアウォール・IDSとの違い
見ている層が違う
ネットワークファイアウォール(ufwやセキュリティグループ)は「どのIPからどのポートへの通信を通すか」を判断します。HTTPの中身は見ないため、80番や443番を開けている以上、SQLインジェクションを含んだリクエストもそのまま通します。IDS/IPSはパケットの内容をパターン照合しますが、TLSで暗号化されたHTTPSの中身は復号しなければ見えず、Webアプリ固有の文脈(このパラメータはIDなのか検索語なのか)も理解しません。
WAFは、TLSを終端したあとのHTTPリクエストとレスポンスを、URL・ヘッダー・クエリ・ボディの単位で解析し、Webアプリへの攻撃パターンに該当するかを判定して遮断します。守る対象が「サーバー」ではなく「アプリケーション層のリクエスト」である点が本質的な違いです。
| 種類 | 見るもの | 防げる例 | 防げない例 |
|---|---|---|---|
| ネットワークFW | IP・ポート・プロトコル | SSHポートへの総当たり、不要ポートへのアクセス | 正規ポートを通るSQLインジェクション |
| IDS/IPS | パケットの内容パターン | 既知のマルウェア通信、スキャン | 暗号化されたHTTPS内の攻撃 |
| WAF | 復号後のHTTPリクエスト・レスポンス | SQLi・XSS・パストラバーサル・既知CVEの悪用 | ロジックの欠陥(他人のデータをIDで取得できる等) |
シグネチャとマネージドルール
WAFの判定の中心はシグネチャ(攻撃パターンの定義)です。「UNION SELECTを含むクエリ」「../を含むパス」「script タグを含むパラメータ」といった正規表現ベースの検知に加え、近年はリクエストの複数の特徴にスコアを付けて閾値を超えたら遮断するアノマリースコアリング方式が主流です。これらのシグネチャ群をベンダーが保守・更新して提供するのがマネージドルールで、新しい脆弱性(CVE)が公開されるとルールが追加され、利用者は自分でパターンを書かなくても防御が更新されます。OWASP Core Rule Set(CRS)はオープンソースの代表的なルールセットで、ModSecurityだけでなく多くの商用WAFの基礎にもなっています。
導入パターンの比較|Cloudflare WAF・AWS WAF・ModSecurity
| 項目 | Cloudflare WAF | AWS WAF | ModSecurity(Nginx/Apache) |
|---|---|---|---|
| 配置 | CDNのエッジ(DNSを向けるだけ) | CloudFront・ALB・API Gatewayに紐づけ | Webサーバー内のモジュール |
| マネージドルール | Cloudflare管理ルール+OWASP CRS(Proプラン以上) | AWS管理ルールグループ+マーケットプレイスの有料ルール | OWASP CRS(自分で更新) |
| 料金体系 | プラン固定(Freeでも基本的な管理ルールあり) | Web ACL・ルール数・リクエスト数の従量課金 | 無料(運用工数がコスト) |
| 誤検知の調整 | ダッシュボードでイベントを見てスキップルール作成 | ルールごとのCountモードとスコープダウン文 | 設定ファイルでルールID除外 |
| 向いている環境 | ドメインをCloudflareで管理できる、運用工数を最小化したい | AWS上でALB/CloudFrontを使っている | オンプレやVPS単体、通信を外部に出せない |
中小規模のWebサービスでは、DNSをCloudflareに移すだけで有効化できるCloudflare WAFが導入の摩擦が最も少なく、AWS上でCloudFrontやALBを既に使っているならAWS WAFが自然です。ModSecurityは自由度が高い一方、ルール更新・チューニング・パフォーマンス影響をすべて自分で面倒を見る必要があり、専任者がいないチームにはおすすめしにくい選択肢です。
AWS WAFを安全に導入する手順
最初は全ルールをCountモードで動かす
マネージドルールをいきなりBlockで有効化すると、既存の正規リクエストがどれだけ引っかかるか予測できません。AWS WAFにはルールの判定だけ記録して遮断はしないCountモードがあるので、次の順序で導入します。
- Web ACLを作成し、AWS管理のCommonRuleSet・KnownBadInputsRuleSet・SQLiRuleSetなどをすべてCountモードで追加する。
- ログをS3またはCloudWatch Logsに出力し、1〜2週間分のCount記録を集める。
- 正規リクエストに反応しているルールを特定し、そのルールだけ除外またはスコープダウンする。
- 問題のないルールからBlockに切り替える。切り替え直後は問い合わせ窓口に「フォームが送れない」報告が来ないか注意する。
# Web ACLにAWS管理ルールをCountモードで追加する(ルール定義の抜粋)
{
"Name": "AWS-AWSManagedRulesCommonRuleSet",
"Priority": 1,
"Statement": {
"ManagedRuleGroupStatement": {
"VendorName": "AWS",
"Name": "AWSManagedRulesCommonRuleSet",
"RuleActionOverrides": [
{ "Name": "SizeRestrictions_BODY", "ActionToUse": { "Count": {} } }
]
}
},
"OverrideAction": { "Count": {} },
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "CommonRuleSet"
}
}
Web ACL全体をCountにするのが OverrideAction、特定ルールだけを個別に上書きするのが RuleActionOverrides です。ALBに紐づける場合は同じリージョン、CloudFrontに紐づける場合はバージニア北部(us-east-1)でWeb ACLを作る必要があります。
レートベースルールで総当たりを止める
マネージドルールはパターン検知が中心で、ログインの総当たりのような「正常な形のリクエストを大量に送る」攻撃には効きません。これはレートベースルールで、一定時間内のIPあたりリクエスト数に上限を設けて対処します。アプリ側のレート制限の設計と役割が重なりますが、WAF側はアプリに届く前に落とせる点、アプリ側はユーザー単位で細かく制御できる点で補完関係にあります。
# /login への5分間のリクエストが同一IPから300回を超えたら遮断
# Web ACLのルールとして直接定義する例
{
"Name": "LoginRateLimit",
"Priority": 0,
"Statement": {
"RateBasedStatement": {
"Limit": 300,
"EvaluationWindowSec": 300,
"AggregateKeyType": "IP",
"ScopeDownStatement": {
"ByteMatchStatement": {
"FieldToMatch": { "UriPath": {} },
"PositionalConstraint": "STARTS_WITH",
"SearchString": "/login",
"TextTransformations": [{ "Priority": 0, "Type": "LOWERCASE" }]
}
}
}
},
"Action": { "Block": {} },
"VisibilityConfig": { "SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "LoginRateLimit" }
}
誤検知の調査と例外設定
「フォームが送れない」が起きる仕組み
WAFの誤検知(False Positive)で最も多いのは、ユーザーが入力した自由記述がシグネチャに一致するケースです。問い合わせ本文に「SELECT文の書き方について」と書いた、住所欄に「--」を含む記号を入れた、CMSの管理画面でHTMLを含む記事を保存した、リッチテキストエディタがscriptに似た文字列を送った、といった状況で、SQLi・XSSのルールが反応します。ファイルアップロードがサイズ制限ルールに当たることもあります。
調査から例外設定までの手順
- ユーザーから報告された時刻・操作・エラー画面(403やCloudflareのブロックページ)を確認する。
- WAFのログで該当リクエストを検索し、どのルールIDが反応したかと、リクエストのどの部分(ヘッダー・ボディ・パラメータ名)が一致したかを特定する。
- 例外を「最小の範囲」で作る。ルール全体を無効化するのではなく、「/contact へのPOSTのbodyパラメータ message に限って、そのルールを適用しない」といった絞り込みを行う。
- 例外を入れた理由と日付を記録し、定期的に見直す。
# AWS WAFのログ(CloudWatch Logs Insights)でブロックされたルールを集計
fields @timestamp, httpRequest.clientIp, httpRequest.uri, terminatingRuleId
| filter action = "BLOCK"
| stats count() by terminatingRuleId, httpRequest.uri
| sort count desc
| limit 20
# Countモードで反応したルール(ラベル)を見る
fields @timestamp, httpRequest.uri, nonTerminatingMatchingRules.0.ruleId
| filter ispresent(nonTerminatingMatchingRules.0.ruleId)
| stats count() by nonTerminatingMatchingRules.0.ruleId
Cloudflareの場合はSecurity → Eventsで同様にルールIDとマッチ箇所を確認でき、「Skip」アクションのカスタムルールで特定パスや特定パラメータに対して管理ルールを迂回させます。ModSecurityでは SecRuleRemoveById や、より安全な SecRuleUpdateTargetById で特定パラメータだけをルールの対象から外します。
ログ監視と、WAFが代替しないもの
ブロック数の急増とゼロの両方を見る
WAFは入れて終わりではなく、ログを見て初めて価値が出ます。見るべきは「ブロック数が急に増えた(攻撃の兆候、または新ルール追加による誤検知)」と「ブロック数がゼロになった(WAFが外れている、ログ出力が止まっている)」の両方です。CloudWatchアラームやCloudflareの通知で、ブロック数の閾値超過と一定期間ゼロの両方を監視対象にしてください。加えて、ブロックされた送信元IPの上位を週次で確認し、同じIPから継続的に来ている場合はIPセットで明示的に遮断すると、マネージドルールの評価コストも下がります。
WAFが守れないもの
WAFは「既知の攻撃パターン」を止める道具であり、アプリの設計上の欠陥は止められません。URLのIDを変えるだけで他人の注文が見える(アクセス制御の不備)、パスワードリセットのトークンが推測できる、業務ロジックの順序をスキップできる、といった問題は正規のリクエストの形をしているため、WAFから見ると正常です。また、WAFを通らない経路(オリジンサーバーへの直接アクセス、内部ネットワークからの通信)は当然守られません。WAFは脆弱性修正までの時間を稼ぐ「保険」であり、フレームワークのアップデートとコードの修正を置き換えるものではない、という位置づけを組織内で共有しておくことが重要です。
トラブル事例:WAF導入後、CMSの記事保存だけが失敗する
症状:AWS WAFでマネージドルールをBlockにした翌日、CMSの管理画面で記事を保存すると403になる。閲覧や短い記事は問題なく、画像やリンクを含む長い記事だけ失敗する。
原因:WAFログを見ると、CommonRuleSetのSizeRestrictions_BODYとCrossSiteScripting_BODYが記事本文のHTMLに反応していた。管理画面のPOSTボディが既定の検査上限を超えており、さらに本文中のiframeタグがXSSシグネチャに一致していた。
対処:管理画面のパス(/admin/ 配下)に限定して、該当2ルールをCountに上書きするスコープダウン文を追加。同時に管理画面自体はIP制限とMFAで保護されているため、WAFのXSS検査に頼らなくてよいと判断した。公開側のフォームには変更を加えず、本文にHTMLを書ける画面だけを例外にすることで、「例外を最小範囲に」の原則を守った。
まとめ
WAFは復号後のHTTPリクエストを解析してアプリケーション層の攻撃を止める仕組みで、ネットワークファイアウォールやIDSとは守る層が異なります。マネージドルールで既知の攻撃パターンを自動更新で防ぎつつ、導入時はCountモードで誤検知を洗い出し、例外は最小範囲で作り、ログのブロック数を継続的に監視してください。同時に、WAFは設計上の欠陥や未修正の脆弱性を代替するものではなく、時間を稼ぐ保険であることを忘れないでください。WAFの導入設計や誤検知のチューニング、脆弱性対策の優先順位づけについては、Harmonic Societyのシステム開発・インフラ支援にご相談ください。
Harmonic Society
この記事の内容、自社の業務でも活かせそうですか?
ローカルLLM・AI・クラウドなどの技術導入を、要件整理からPoC・社内展開まで代表エンジニアが伴走します。オンライン対応・全国OK。まずは30分の無料相談から。売り込みはしません。
関連記事
Related / 9 articles
Notes & Insights
- プログラミング
DDoS攻撃の仕組みと対策入門|レイヤー別の防御とCDN・クラウドの活用
DDoS攻撃をボリューム型・プロトコル型・アプリ層に分けて仕組みを解説し、自前サーバーで防げない理由、CloudflareやAWS Shieldの標準防御、オリジンIPの隠し方、レートリミットとBot対策、攻撃を受けたときの初動、費用が跳ね上がるDenial of Walletへの備えまでわかります。
- プログラミング
セキュリティヘッダー入門|CSP・HSTS・X-Frame-Optionsの設定と効果を実践解説
CSP・HSTS・X-Frame-Options・X-Content-Type-Optionsなど主要セキュリティヘッダーが防ぐ攻撃と、CSPのReport-Onlyからの段階導入、nonce/hash、HSTS preloadの不可逆リスク、Nginx・Next.js・Astroでの設定例、確認方法を解説します。
- プログラミング
クラウドの通信費(Egress)入門|データ転送量課金の仕組みと転送コストを抑える設計
クラウドの「受信無料・送信有料」の原則、AZ間・リージョン間・インターネット向けの単価差、NATゲートウェイ処理料の罠、CDNで転送量を減らす方法、バックアップやログ転送の見落とし、請求書で転送料を特定する手順を解説。想定外の請求を防げます。
- プログラミング
秘密情報をGitに入れない仕組み|.gitignore・git-secrets・履歴から漏れた鍵の削除
APIキーや.envをGitにコミットしてしまう典型経路と、.gitignore・.env.exampleの運用、pre-commitでのgitleaks検知、GitHub secret scanningの活用、漏れた鍵の無効化と履歴書き換え(git filter-repo)の手順を解説。仕組みで再発を防げます。
- プログラミング
開発・ステージング・本番環境の分離設計|環境差分をなくす構成とアクセス制御
開発・ステージング・本番それぞれの目的と、構成をコードで揃える方法、環境別の設定注入、本番データを使わないテストデータ戦略、ステージングの保護(Basic認証・IP制限・noindex)、コストを抑える運用までを解説。環境差分による本番障害を防げます。
- プログラミング
ngrok・Cloudflare Tunnelでローカルを公開|Webhook開発とデモ環境の作り方
NAT内のローカル環境にStripeやLINEのWebhookを届けるトンネリングの仕組みを解説。ngrok・Cloudflare Tunnel・localtunnelの比較、固定ドメインと認証、リクエスト検査、公開時のセキュリティ、自宅サーバー公開への応用までわかります。
- プログラミング
ローカル開発環境のHTTPS化|mkcert・hostsファイル・自己署名証明書の正しい使い方
ローカル開発をHTTPS前提にすべき理由(Secure Cookie・Service Worker・OAuth)と、mkcertでローカルCAを作りhostsで独自ドメインを割り当ててVite・Next.js・Dockerで使う手順を解説。証明書警告を無視する癖の危険も理解できます。
- プログラミング
localhost・0.0.0.0・127.0.0.1の違い|ポートとUnixソケットを理解して「つながらない」を解決
localhost・127.0.0.1・0.0.0.0の意味の違い、Dockerで外から接続できない原因、host.docker.internal、ポート競合の調べ方、Unixソケットの利点と権限、1024未満ポートの制約を解説。「つながらない」を仕組みから解決できます。
- プログラミング
GitOps入門|ArgoCD・FluxでGitをインフラの正とするデプロイ運用
GitOpsのPush型とPull型の違い、差分検知と自動同期の仕組み、リポジトリ構成、ArgoCDの最小導入手順までを解説。git revertで戻せるデプロイ運用が理解でき、Kubernetes以外への応用の考え方もわかります。
Harmonic Society
「読んで終わり」にせず、自社の業務で試してみませんか?
AI・ローカルLLM・クラウドの導入を、要件整理からPoC・社内展開まで代表エンジニアが伴走します。オンライン対応・全国OK・売り込みなし。
無料・30分・オンラインOK|1営業日以内に返信します