2018.11.08

【AWS WAF】テンプレートでお手軽にWAFを構築しよう!【後編】

  • このエントリーをはてなブックマークに追加
  • follow us in feedly
本ページは2017年11月時点の情報を元に記載しています。

前編について

  • 前編では以下について説明しました。
    • AWSにおけるWAF
    • 導入前に理解しておくべきこと
    • テンプレートの展開手順
  • 後編では、設定項目の解説やテンプレートの詳細を説明します。

AWS WAF 設定の理解

階層構造

  • まず最低限の用語を理解しましょう。以下の階層構造になっています。
    • Web ACL → Ruleをまとめたもの
      • Rule → Conditionをまとめたもの
        • Condition → 条件(シグネチャの実体)をまとめたもの

Web ACLs

  • Rulesをまとめたものです。
  • AWS WAFをALBやCloudFrontに適用する単位となっています。
  • 1つのALB,CloudFrontに対して複数のWeb ACLsを適用することはできません。
    • サイト名などを組合せた名前にすると便利です。

Rules

  • Conditionsをまとめたものです。
  • 各ルールにたいしてアクション(ブロック、許可、カウント)を選択できます。
  • 各ルールに順番を定めることができます。数字の若い順に評価されます。運用後ルールを挿入する可能性もあるのでルールの数字は一定のバッファを設けたほうがよいです。(10の次は20など)

Conditions

  • 条件(シグネチャの実体)をまとめたものです。
  • 予め条件の枠組みが6個定義されています。
    • クロスサイトスクリプティング [Cross-site scripting]
    • 地理情報 [Geo match]
    • IPアドレス [IP addresses]
    • サイズ制約 [Size constraints]
    • SQLインジェクション [SQL injection]
    • 文字列と正規表現 [String and regex matching]
  • 上記の枠組みから必要なものを選んで設定を定めます。
    • 設定する内容は、Conditions毎に異なります。
      • クロスサイトスクリプティング, SQLインジェクション
        • どのようなHTTP(s)アクションに対し(filter)、 どのような前処理をするか(Transformation)、 を定めます。
      • サイズ制約, 文字列と正規表現
        • どのようなHTTP(s)アクションに対し(filter)、 どのような前処理をするか(Transformation)、サイズや文字列を定めます。
      • 地理情報, IPアドレス
        • 制御したい地域やIPレンジなどを定めます。
    • 「Transformation」とは
      • 一見分かりづらいのですが、ただの前処理です。以下が選択できます。
        • なし
        • Convert to lowercase
        • HTML decode
        • Normalize whitespace
        • Simplify command line
        • URL decode
      • 例えばURIをフィルタ対象にする場合は「URL decode」がほぼ必須になるでしょう。マルチバイト文字などはパーセントエンコーディングされていますから、デコードしないと文字列とマッチさせることも困難です。また、大文字小文字を考慮したくない場合は「Convert to lowercase」で強制小文字変換し、小文字でマッチさせます。

今回のテンプレートで展開されるルールについて

  • テンプレートで展開される10個のルールについて以下に説明していきます。
    • 以下の観点で記載しています。
      • 見出しの先頭にルールの優先順位を記載しています。若番から先に評価されていきます。
      • 「アクション」「コンディション」および設定値はデフォルト値を記載しています。
        • 「コンディション」に[not扱い]と記載しているものは否定ルールですので「そのルールに該当しない場合」にマッチします。
      • 「概要」「備考」は弊社見解を記載していますのであくまで参考としてください。
      • 「OWASP TOP 10 (2017)との対応」については以下を参考にしています。

10. generic-restrict-sizes

  • アクション:block
  • コンディション:generic-size-restrictions
  • 概要:ボディやURL等のサイズが異常な場合はブロックする。
  • OWASP TOP 10 (2017)との対応:A7 – Insufficient Attack Protection
  • 備考:アプリのクッキーサイズで引っかかることもある。環境に応じてカスタマイズする。
The length of the Header 'cookie' is greater than 4093.
The length of the Query string is greater than 1024.
The length of the URI is greater than 512. 
generic-size-restrictions

20. generic-detect-blacklisted-ips

  • アクション:block
  • コンディション:generic-match-blacklisted-ips
  • 概要:ソースIPがプライベートセグメントに偽装されている場合はブロックする。
  • OWASP TOP 10 (2017)との対応:無し
  • 備考:必要に応じてカスタマイズする。プライベートセグメントに限らず追加可能。但しCIDRのマスク範囲は限られているため注意が必要。
    • [追記]2018年6月5日より、CIDRのマスク制限がなくなりました!
172.16.0.0/16
169.254.0.0/16
192.168.0.0/16
10.0.0.0/8
127.0.0.1/32 
generic-match-blacklisted-ips

30. generic-detect-bad-auth-tokens

  • アクション:block
  • コンディション:generic-match-auth-tokens
  • 概要:URLデコード後のヘッダに特定の文字列(JSON Webトークン、クッキーID)が含まれる場合はブロックする。
  • OWASP TOP 10 (2017)との対応:A2 – Broken Authentication and Session Management
  • 備考:「特定の文字列」には例が記載されているため、環境に応じてカスタマイズする
Header 'authorization' ends with: ".TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ" after decoding as URL.
Header 'cookie' contains: "example-session-id" after decoding as URL. 
generic-match-auth-tokens

40. generic-mitigate-sqli

  • アクション:block
  • コンディション:generic-detect-sqli
  • 概要:デコード後の[クッキー/ボディ/クエリストリング/URI]にSQLインジェクションの挙動がある場合はブロックする。
  • OWASP TOP 10 (2017)との対応:A1 – Injection
  • 備考:無し
Header 'cookie' contains SQL injection threat after decoding as HTML tags.
Header 'cookie' contains SQL injection threat after decoding as URL.
Query string contains SQL injection threat after decoding as HTML tags.
Body contains SQL injection threat after decoding as URL.
Body contains SQL injection threat after decoding as HTML tags.
URI contains SQL injection threat after decoding as HTML tags.
Query string contains SQL injection threat after decoding as URL.
URI contains SQL injection threat after decoding as URL. 
generic-detect-sqli

50. generic-mitigate-xss

  • アクション:block
  • コンディション:generic-detect-xss
  • 概要:デコード後の[ヘッダ/ボディ/クエリストリング/URI]にクロスサイトスクリプティングの挙動がある場合はブロックする。
  • OWASP TOP 10 (2017)との対応:A3 – Cross-Site Scripting (XSS)
  • 備考:誤検知が起きやすいため、充分なチューニング期間を設けて検証する。
URI contains a cross-site scripting threat after decoding as HTML tags.
Header 'cookie' contains a cross-site scripting threat after decoding as URL.
Query string contains a cross-site scripting threat after decoding as HTML tags.
Body contains a cross-site scripting threat after decoding as HTML tags.
URI contains a cross-site scripting threat after decoding as URL.
Query string contains a cross-site scripting threat after decoding as URL.
Body contains a cross-site scripting threat after decoding as URL.
Header 'cookie' contains a cross-site scripting threat after decoding as HTML tags. 
generic-detect-xss

60. generic-detect-rfi-lfi-traversal

  • アクション:block
  • コンディション:generic-match-rfi-lfi-traversal
  • 概要:デコード後の[クエリストリング/URI]にリモートファイルインクルード、ローカルファイルインクルード、ディレクトリトラバーサルで用いられる文字列が含まれている場合はブロックする。
  • OWASP TOP 10 (2017)との対応:A4 – Broken Access Control
  • 備考:無し
URI contains: "://" after decoding as URL.
Query string contains: "://" after decoding as HTML tags.
URI contains: "://" after decoding as HTML tags.
Query string contains: "://" after decoding as URL.
Query string contains: "../" after decoding as URL.
URI contains: "../" after decoding as URL.
URI contains: "../" after decoding as HTML tags.
Query string contains: "../" after decoding as HTML tags. 
generic-match-rfi-lfi-traversal

70. generic-detect-php-insecure

  • アクション:block
  • コンディション:generic-match-php-insecure-uri
  • コンディション:generic-match-php-insecure-var-refs
  • 概要:PHPの設定不備を狙うアクセスをブロックする。
  • OWASP TOP 10 (2017)との対応:A5 – Security Misconfiguration
  • 備考:phpを利用しない場合は不要と思われる。
URI ends with: "/" after decoding as URL.
URI ends with: "php" after decoding as URL. 
generic-match-php-insecure-uri
Query string contains: "safe_mode=" after decoding as URL.
Query string contains: "auto_prepend_file=" after decoding as URL.
Query string contains: "_SERVER[" after decoding as URL.
Query string contains: "open_basedir=" after decoding as URL.
Query string contains: "disable_functions=" after decoding as URL.
Query string contains: "_ENV[" after decoding as URL.
Query string contains: "allow_url_include=" after decoding as URL.
Query string contains: "auto_append_file=" after decoding as URL. 
generic-match-php-insecure-var-refs

80. generic-enforce-csrf

  • アクション:block
  • コンディション:generic-match-csrf-method
  • コンディション:generic-match-csrf-token [not扱い]

  • 概要:クロスサイトリクエストフォージェリ(CSRF)対策用トークンがない場合はブロックする
  • OWASP TOP 10 (2017)との対応:A8 – Cross-Site Request Forgery (CSRF)
  • 備考:すべてのPOSTメソッドにCSRF用トークン(36文字)を強制させるため、副作用が強い。アプリ側で必要な箇所のみトークンを発行させ、このルールはAllowもしくは削除とすることが多い。
HTTP method matches exactly to: "post" after converting to lowercase. 
generic-match-csrf-method
The length of the Header 'x-csrf-token' is equal to 36. 
generic-match-csrf-token

90. generic-detect-ssi

  • アクション:block
  • コンディション:generic-match-ssi
  • 概要:SSI設定不備を狙うアクセスをブロックする。
  • OWASP TOP 10 (2017)との対応:A9 – Using Components with Known Vulnerabilities
  • 備考:SSIを利用しない場合は不要と思われる。
URI ends with: ".cfg" after converting to lowercase.
URI ends with: ".backup" after converting to lowercase.
URI ends with: ".bak" after converting to lowercase.
URI ends with: ".log" after converting to lowercase.
URI ends with: ".config" after converting to lowercase.
URI starts with: "/includes" after decoding as URL.
URI ends with: ".conf" after converting to lowercase.
URI ends with: ".ini" after converting to lowercase. 
generic-match-ssi

100. generic-detect-admin-access

  • アクション:block
  • コンディション:generic-match-admin-url
  • コンディション:generic-match-admin-remote-ip [not扱い]
  • 概要:一般的な管理用URLに用いられるパスに外部からアクセスした場合にブロックする。
  • OWASP TOP 10 (2017)との対応:A4 – Broken Access Control
  • 備考:必要に応じてカスタマイズする
URI starts with: "/admin" after decoding as URL. 
generic-match-admin-url
127.0.0.1/32 
generic-match-admin-remote-ip

このテンプレートで提供されていないカテゴリ (OWASP TOP10 2017 RC版を基準として)

  • ご紹介したテンプレートはセキュリティリスクの「緩和」を目的としているものであり、一定の基準を「満たす」ためのものではありません。当然上記ルールがOWASP TOP10と対応しているからといってそのカテゴリのリスクを十全に回避するものではありませんが、明らかに対応していないリスクについては気になるところですのでそこにポイントを絞って解説します。

A6 – Sensitive Data Exposure (機密データの露出)

  • 個人情報やクレジットカード情報など、秘匿すべきデータのセキュリティリスクを記述したものです。
  • 一般的に「何を機密とするか」は企業によって異なるため、このカテゴリへの対策をWAFで自動化するのは困難とされています。
  • セキュリティリスク(例)
    • 機密情報の漏洩
  • 基本的な対策(例)
    • 暗号化(データおよび通信)
    • 新しい/強い暗号化アルゴリズムを利用する
    • 不要な機密情報は保持しない
  • 上述した対策はAWSでも実装可能です(AWS WAFの機能としてではなくRDS/S3/ELB等の機能を利用)。
  • WAFアプライアンスでは、以下のような機能をもっているものもあります。
    • クレジットカード情報など明らかに機密情報と判断できるデータがアウトバウンドに流れている場合はブロックする。
    • 機密情報に対してアクセス監査機能を持たせることで、中間者攻撃(MITM)や内部メンバーなど、復号化できる位置にいる者の犯行を検知する。

A10 – Underprotected APIs (保護されていないAPI)

  • APIで構成されたサイトも通常のWebサイトと同様にセキュリティリスクがあることを示したものです。
    • APIへのWAF適用は考慮から漏れることが多いためカテゴライズされています。
  • セキュリティリスク(例)
    • 通常のWebサイトと同様のリスク(SQLi,セッション管理不備等)
    • パラメータ改ざん
    • APIへのDDoS
  • 基本的な対策(例)
    • SQLi対策、セッション保護
    • パラメータのチェック
    • IPレピュテーション
  • 上述した対策は、AWSでは例としてAPI gatewayの前段にCloudFront+AWS WAFを配置することで、全てではありませんが実装が可能です。
    • ※[追記]2018/11/5よりAPI Gatewayにも直接設置できるようになりました!
    • パラメータ改ざんなどはConditionsの[String and regex matching]を駆使しチェックする形になります。
  • WAFアプライアンスでは、以下のような機能をもっているものもあります。
    • APIのパラメータや実行順序が予め定義したものと合致しているかチェックし、適合しない場合はブロックする。

さいごに

いかがでしたでしょうか。

AWS WAFテンプレートを展開し、少しアレンジするだけで最低限のWAFをすぐに用意できることがイメージ頂けたら幸いです。ローンチが簡単にできることで導入検証のハードルも下がるのではと思います。

ご紹介したようにAWS WAFは気軽に使うことができますが、セキュリティ対策としては考慮すべきポイントが様々にあります。パブリッククラウドの撤退理由の1つとしてセキュリティ機能の不安が挙げられることがありますが、守るべきものをどのような基準で守るかという整理ができていれば、AWSのセキュリティ関連サービスで要件を満たすケースもあるのではと私は考えています。

セキュリティベンダーに丸投げするほどの予算がないなど、なんとか自前で対策したいというお客様に、我々テラスカイAWS事業部はソリューションをご提案しお手伝いをすることができます。ぜひお気軽にお問い合わせください。最後までお読み頂きありがとうございました。
37 件

関連する記事