Webアプリケーションファイアウォール(WAF)は、HTTPトラフィックを監視・フィルタリングし、SQLインジェクションやXSSなどの攻撃からアプリケーションを保護するセキュリティソリューションです。従来のネットワークファイアウォールがL3/L4で動作するのに対し、WAFはL7(アプリケーション層)で動作する点が大きな違いです。
筆者はこれまで複数のプロジェクトでWAFの導入・運用に携わってきましたが、正しく設計しないと「入れたのに守れていない」あるいは「正常なリクエストまでブロックしてしまう」という事態に陥ります。本記事では、実務で得た知見をもとに、WAFの設計から運用までを包括的に解説します。
WAFが防御すべき攻撃は多岐にわたりますが、OWASP Top 10をベースに優先度を設定するのが現実的です。代表的な攻撃と対応するルール設計を見ていきましょう。
最も古典的でありながら、いまだに被害が絶えない攻撃です。WAFではリクエストパラメータ内のSQL構文パターンを検知します。
# AWS WAF v2でのSQLインジェクション対策ルール例(Terraform)
resource "aws_wafv2_web_acl" "main" {
name = "app-waf"
scope = "REGIONAL"
default_action {
allow {}
}
rule {
name = "sql-injection-protection"
priority = 1
action {
block {}
}
statement {
sqli_match_statement {
field_to_match {
body {}
}
text_transformation {
priority = 1
type = "URL_DECODE"
}
text_transformation {
priority = 2
type = "HTML_ENTITY_DECODE"
}
}
}
visibility_config {
sampled_requests_enabled = true
cloudwatch_metrics_enabled = true
metric_name = "SQLInjectionRule"
}
}
}
ポイントはテキスト変換(text_transformation)を複数段階で適用しますことです。攻撃者はURLエンコードやHTMLエンティティエンコードを組み合わせて検知を回避しようとします。デコード処理を連鎖させることで、難読化された攻撃パターンも捕捉できます。
XSS攻撃はユーザーのブラウザ上で不正なスクリプトを実行させる手法です。WAFではリクエスト内のスクリプトタグやイベントハンドラのパターンを検知します。
# カスタムルールでXSSパターンを検知する正規表現例
xss_patterns = [
r']*>',
r'javascript:',
r'on(load|error|click|mouseover)\s*=',
r'eval\s*\(',
r'document\.(cookie|location|write)',
]
WAFの導入で最も重要な原則は、いきなりブロックモードで本番投入しませんことです。まずはカウントモード(モニタリングモード)で運用し、誤検知の傾向を把握してからブロックに切り替えます。
業務システムでは、正常なリクエストがWAFルールに引っかかるケースが頻繁に発生します。例えば、CMSの管理画面でHTMLタグを含む投稿を行う場合、XSSルールが誤検知する可能性があります。
# 特定パスへのリクエストをXSSルールから除外する設定例
rule {
name = "xss-protection-with-exclusion"
priority = 2
action {
block {}
}
statement {
and_statement {
statement {
xss_match_statement {
field_to_match {
body {}
}
text_transformation {
priority = 1
type = "NONE"
}
}
}
statement {
not_statement {
statement {
byte_match_statement {
search_string = "/admin/articles"
field_to_match {
uri_path {}
}
positional_constraint = "STARTS_WITH"
text_transformation {
priority = 1
type = "LOWERCASE"
}
}
}
}
}
}
}
}
WAFはアプリケーション攻撃の防御だけでなく、DDoS緩和やBot制御にも活用できます。レートベースのルールを設定することで、特定のIPアドレスからの過剰なリクエストを自動的にブロックできます。
# レートベースルールの設定例
rule {
name = "rate-limit"
priority = 0
action {
block {}
}
statement {
rate_based_statement {
limit = 2000
aggregate_key_type = "IP"
}
}
}
この例では、5分間に2000リクエストを超えるIPアドレスを自動的にブロックします。ただし、企業のプロキシ経由のアクセスが多い環境では閾値を慎重に設定する必要があります。
WAFのログは攻撃の傾向を把握し、ルールを改善するための貴重な情報源です。AWS WAFの場合、ログをKinesis Data Firehose経由でS3に保存し、Athenaで分析するのが定番の構成です。
運用で特に注目すべきメトリクスは以下の通りです。
WAFはセキュリティの重要な構成要素ですが、銀の弾丸ではありません。アプリケーション側でのバリデーション、セキュアコーディング、定期的な脆弱性診断と組み合わせてこそ効果を発揮します。導入後も継続的にルールをチューニングし、新たな攻撃手法に対応し続けることが求められます。「設定して放置」が最も危険なアンチパターンであることを、ぜひ覚えておいてください。