AWSセキュリティ【AWS WAF】:AWS提供のOWASP Top 10 テンプレートからセットアップ

OWASPとはOpen Web Application Security Projectの略で、セキュアなアプリケーションの開発・購入・運用を推進するために作られたオープンなコミュニティです。

セキュリティに関連した重大な脆弱性リスト「OWASP Top 10」が知られています。 世界中のセキュリティ専門家が参加しており、各国に支部があり、日本にはOWASP Japanが存在します。

AWS WAF を適用しようとしたときに、まず障壁となるのが、WAFのコンフィグ設定作業だと思われます。
WAF・コンフィグの障壁に対する解決策に、AWSが公開しているテンプレートファイルと AWS WAF Marketplace があります。

AWS提供のOWASP Top 10 テンプレートファイル

2017年4月に、OWASP Top 10が新しくリニューアルされました。 以下がその一覧です。

A1 インジェクション
A2 壊れた認証とセッション管理
A3 クロスサイトスクリプティング(XSS)
A4 ブロークン・アクセス制御(NEW)
A5 セキュリティの設定ミス
A6 機密データの露出
A7 不十分な攻撃からの保護(NEW)
A8 クロスサイトリクエストフォージェリ(CSRF)
A9 既知の脆弱性を持つコンポーネントを使用
A10 UnderprotectedのAPI(NEW)
Old Top 2013 A10 未確認のリダイレクトと転送

AWS WAFへ実装について、CloudFormationテンプレートのサンプルをダウンロードできます。

https://aws.amazon.com/jp/about-aws/whats-new/2017/07/use-aws-waf-to-mitigate-owasps-top-10-web-application-vulnerabilities/

https://s3.us-east-2.amazonaws.com/awswaf-owasp/owasp_10_base.yml

AWS WAF (CloudFormatioテンプレート・サンプル)の注意点

入力フォームに入力される文字列にHTMLタグ名やjavascriptハンドラ名などの一部が含まれると、XSS攻撃と判定されブロックされてしまうケースがあり、正しい内容でも意図しないブロックが発生することがあります。
2018年8月30日に機能改善され、ブロック理由がわかるようになり、推測し易くなりましたが、注意が必要です。
※ WordPressの管理画面は「generic-detect-ssi」ルール(後述)でブロックされます。
  私は、ルールのアクションをWordPressのメンテナンス時に、一時的に「Count」にして、機能を無効にして対応しています。

Webリクエストをきめ細かく制御するWebアクセスコントロールリスト (Web ACL) の設計上の上限制限値に対して、上限緩和申請が可能です。

リソース1 リージョン、1 アカウントあたりのデフォルトのクォータ
ウェブ ACLs の最大数100
ルールグループの最大数100
ウェブ ACL あたりのウェブ ACL キャパシティーユニット (WCU) の最大数1500
ルールグループあたりの最大 WCUs1500
IP セットの最大数100
ウェブ ACL あたりの 1 秒あたりの最大リクエスト数
(Application Load Balancer にのみ適用)
25000

AWS WAF Marketplace

AWS WAF MarketplaceはAWS WAFサービスのためにサードパーティが用意したルールセットを使ったサービスです。
最初から整備されたルールなので、提供元サードパーティのサポートを受けながら運用ができます。
WAFが影響したトラブル時の判断などに対応しやすくなると思われ、運用面での不安を軽減できると思われます。

以下のように、AWS WAFのメニューで「Marketplace」を選択し、ルールセットを購入し、数クリックで簡単にWAFに導入できます。

OWASP Top 10 テンプレートからセットアップ

前準備1:CloudFormation用ロールの作成

「ロールの作成」をクリック

「CloudFormation」をクリック

「CloudFormation」を選択

ユースケースの選択に「CloudFormation」が
選択された状態で「次のステップ: アクセス権限」
をクリック

「AdministratorAccess」
ポリシーをチェック「次のステップ: タグ」
をクリック

Nameタグに「Cloudformation_role」(任意)と設定

「次のステップ: 確認」
をクリック

「ロールの作成」をクリック

前準備2: CloudFormationにてスタックを作成

※ CloudformationでCreate Stackするリージョンで、どのリージョンのWAF Ruleになるかが決まるので注意!!

「スタックの作成」をクリック 「スタックの作成」
をクリック
「ファイルの選択」でテンプレートを選んで、「次へ」

「ファイルの選択」
でテンプレート
を選んで、

「次へ」

スタック名を「waf-owasp」(任意)と設定

スタック名を
「waf-owasp」(任意)
と設定

「次へ」をクリック

「Cloudformation_role」ロールを「IAMロール」に指定

Nameタグに
「waf-owasp」と設定

作成した「Cloudformation_role」
ロールを「IAMロール」
に指定し、

「次へ」をクリック

「スタックの作成」をクリック 「スタックの作成」
をクリック
CloudFormation用テンプレート「waf-owasp」スタックが作成された AWS WAF設定用のCloudFormation用
テンプレートファイル(yml)
をアップロードした「waf-owasp」スタック
が作成された

AWS提供のOWASP Top 10 テンプレートファイルを使った、AWS WAF の設定

「サービス」メニューより「WAF & Shield」を選択

「Switch to AWS WAF Classic」をクリック
※ 「Web ACLs」をクリックして、入っていったシーケンスではS3コンフィグをうまく指定できなかったので、「Switch to AWS WAF Classic」から入った

「Switch to AWS WAF Classic」
をクリック

 東京リージョンを選択 東京リージョンを選択
「Create web ACL」をクリック 「Create web ACL」をクリック

上記画面の設定内容

  • Web ACL name   任意の名前。セットした内容が反映された。
  • Region       OWASP10テンプレートを置いたS3のリージョン(東京リージョン)
  • Resource type to associate web ACL  「Application load balancer」:ロードバランサーを指定
  • AWS resource to associate       稼働しているロードバランサーを指定

OWASP10テンプレートをを利用するため
何もせず、「Next」をクリック

Default actionは
「Allow all requests that don’t match any rules」
を選択

AWS WAF 設定

以下の階層構造になっています。

  • Web ACL → Ruleをまとめたもの
  • Rule → Conditionをまとめたもの
  • Condition → 条件(シグネチャの実体)をまとめたもの

■Web ACLs

Rulesをまとめたもの。ALBやCloudFrontの適用単位。複数のWeb ACLsは適用できない。

■Rules

Conditionsをまとめたもの。ルールに対するアクション(ブロック、許可、カウント)を選択。ルール順番は数字の若い順。

■Conditions条件をまとめたもの。設定パターンは6個。

  • クロスサイトスクリプティング (HTTP or HTTPS):アクション → (filter)、前処理:(Transformation)
  • 地理情報   制御したい地域
  • IPアドレス  IPレンジ
  • サイズ制約
  • SQLインジェクション
  • 文字列と正規表現

■テンプレートで展開されるルール

10. generic-restrict-sizes

アクション:block
コンディション:generic-size-restrictions
ボディやURL等のサイズが異常な場合はブロック

20. generic-detect-blacklisted-ips

アクション:block
コンディション:generic-match-blacklisted-ips
ソースIPのあり得ない値の場合はブロック(設定内容は確認要)

30. generic-detect-bad-auth-tokens

アクション:block
コンディション:generic-match-auth-tokens
ヘッダに特定の文字列(JSON Webトークン、クッキーID)が含まれる場合はブロック

40. generic-mitigate-sqli

アクション:block
コンディション:generic-detect-sqli
[クッキー/ボディ/クエリストリング/URI]にSQLインジェクションの挙動がある場合はブロック

50. generic-mitigate-xss

アクション:block
コンディション:generic-detect-xss
[ヘッダ/ボディ/クエリストリング/URI]にクロスサイトスクリプティングの挙動がある場合はブロック

60. generic-detect-rfi-lfi-traversal

アクション:block
コンディション:generic-match-rfi-lfi-traversal
[クエリストリング/URI]に
リモートファイルインクルード / ローカルファイルインクルード / ディレクトリトラバーサル
で用いられる文字列が含まれている場合ブロック

70. generic-detect-php-insecure

アクション:block
コンディション:generic-match-php-insecure-uri generic-match-php-insecure-var-refs
PHPの設定不備を狙うアクセスをブロック

80. generic-enforce-csrf

アクション:block
コンディション:generic-match-csrf-method generic-match-csrf-token [not扱い]
クロスサイトリクエストフォージェリ(CSRF)対策用トークンがない場合はブロック

90. generic-detect-ssi

アクション:block
コンディション:generic-match-ssi
SSI設定不備を狙うアクセスをブロック

100. generic-detect-admin-access

アクション:block
コンディション:generic-match-admin-url generic-match-admin-remote-ip [not扱い]
管理用URLパスの外部アクセスブロック(管理用URLを設定)
設定内容を確認 設定内容を確認して、

「Confirm and create」
をクリック

Web ACL 作成 成功!! Web ACL 作成 成功!!

設定の翌日の朝、WAF稼働状況をチェック!!

「AWS WAF Classic」 → 「Web ACLs」
※ なぜだかGoogle Chromeならば、AWS WAF Classicに切り替えられるけど、Egdeだと切り替えられなかった?

generic-detect-php-insecure でブロックした内容を確認
generic-detect-php-insecure でブロックした内容を確認
generic-detect-rfi-lfi-traversal でブロックした内容を確認
generic-detect-rfi-lfi-traversal でブロックした内容を確認
generic-match-ssi でブロックした内容を確認
generic-match-ssi でブロックした内容を確認
generic-enforce-csrf でブロックした内容を確認
generic-enforce-csrf でブロックした内容を確認
generic-detect-sqli でブロックした内容を確認
generic-detect-sqli でブロックした内容を確認
generic-mitigate-xss でブロックした内容を確認
generic-mitigate-xss でブロックした内容を確認

※ generic-detect-rfi-lfi-traversal generic-enforce-csrf generic-mitigate-xss では通信をブロックしたことがわかる

※ WordPressの管理画面は「generic-detect-ssi」ルール(後述)でブロックされます。
  WordPressのメンテナンス時は、ルールのアクションを一時的に「Count」にして、機能を無効にします。
  「Edit web ACL」をクリックして、変更できます。メンテが終わったら、「block」に戻します。

AWS Shield Standard と AWS Shield Advanced の違い

※ 今回、アドバンスドは有効化していない

AWSセキュリティ TIPSはこちら!

「セキュリティ機能全体像」はこちら!