忙しい人のための Use AWS WAF to Mitigate OWASP’s Top 10 Web Application Vulnerabilities メモ

こんにちは、ひろかずです。

2017年7月に「Use AWS WAF to Mitigate OWASP’s Top 10 Web Application Vulnerabilities」が公開されました。
日本語翻訳されていないので、なかなか読めていない方もいると思います。
リリースから少し時間が経ってしまいましたが、読了したので一筆書きます。

#どんなドキュメントか
OWASP Top10 で上っている各項目についての解説と、各項目についてAWS WAFでどのような対応ができるかを記載したもの。
Conditionを作る上でのアドバイスも記載されている。

#参照ドキュメント
[Use AWS WAF to Mitigate OWASP’s Top 10 Web Application Vulnerabilities](https://d0.awsstatic.com/whitepapers/Security/aws-waf-owasp.pdf)

#A1 – Injection
SQLインジェクション攻撃は、比較的簡単に検出できるが、バックエンドの構造によって複雑さが変わるため、アプリケーション側での対応も必要。
cookieやカスタムヘッダをデータベース参照に使う場合は、Conditionで検査対象とするように設定すること。
リクエスト中にクエリを流す事を是としているサービスの場合、対象URLを検知除外(バイパス)するような設定を検討すること。

#A2 – Broken Authentication and Session Management
String Matchを活用して、盗まれた(怪しい)トークンを「安全のために」ブラックリストに登録する
デバイスのロケーションが異なるトークンを検出する等、ログから悪性利用をしているトークンを分析して、ブラックリストに登録するような使い方。
Rate-basedルールを用いて、認証URLを総当り攻撃を防ぐ施策も有効。

#A3 – Cross-Site Scripting (XSS)
XSS攻撃は、HTTPリクエストで特定のキーHTMLタグ名を必要とするため、一般的なシナリオで比較的簡単に軽減できる。
BODYやQUERY_STRING, HEADER: Cookieを検査するのが推奨される。
URLを検査対象とすることは一般的ではないが、アプリケーションが短縮URL使っていると、パラメータはURLパスセグメントの一部として表示され、クエリ文字列には表示されない（後でサーバー側で書き換えられる）
CMSエディタ等、たくさんHTMLを生成するサービスには効果は薄い。
対象URLを検知除外(バイパス)する場合は、別途対策を検討すること。
加えて、`<script>`タグを多用するイメージ(svgグラフィックフォーマット)やカスタムデータも誤検知率が高いので調整が必要。

#A4 – Broken Access Control
2017年から新たに登場
認証ユーザーの制限が適切に動作せず、必要以上に内部アプリケーションオブジェクト(不正なデータの公開、内部Webアプリケーション状態の操作、パストラバーサル、リモート/ローカルファイルの呼び出し)を操作できるというもの。
機能レベルのアクセス制御の欠陥は、一般的に後で追加されたアプリケーションで発生する。
アクセスレベルは、呼び出し時に一度検証されるが、その後に呼び出される様々なサブルーチンについては、都度検証されない。
呼び出し元のコードが、ユーザーの代わりに他のモジュールやコンポーネントを呼び出す暗黙的な信頼ができてしまう。
アプリケーションが、アクセスレベルやサブスクリプションレベルに応じてコンポーネントへアクセスさせる場合は、呼び出しの都度、検証する必要がある。

AWS WAFとしては、「../」や「://」をQUERY_STRINGやURIに含むかを検証することで、リモート/ローカルファイルの呼び出しを検出できる。
これも、リクエスト中に「../」や「://」を含む事を是とするアプリケーションには効果は薄い。
管理モジュール、コンポーネント、プラグイン、または関数へのアクセスが既知の特権ユーザーのセットに限定されている場合、Byte_MatchとIPSetの組み合わせでアクセスを制限することができる。

認証要求がHTTPリクエストの一部として送信され、JWTトークン(のようなもの)でカプセル化されている場合

- Lambda@Edgeファンクションを用いて、関連リクエストパラメータがトークン内のアサーションおよび承認と一致することを確認することで、権限不適合リクエストはバックエンドに届く前に拒否することができる。

#A5 – Security Misconfiguration
セキュリティの影響を受けるパラメータの設定ミスは、アプリケーションだけではなく、OSやミドルウェア、フレームワーク全てにおいて発生し得る。
セキュリティの影響を受けるパラメータの設定ミス例

- ApacheのServerTokens Full（デフォルト）構成
- 本番Webサーバーでデフォルトのディレクトリ一覧を有効にしたまま
- エラーのスタックトレースをユーザーに戻すアプリケーション
- PHPの脆弱なバージョンと組み合わせて、HTTPリクエストを介して内部サーバ変数を上書き

AWS WAFとしては、パラメータの設定ミスを悪用するHTTPリクエストパターンが認識可能な場合に限り対応可能。

- A4 – Broken Access Controlと同様に、特定パスやコンポーネントに対してByte_MatchとIPSetの組み合わせでアクセスを制限を行う。(Wordpress管理画面 等)
- 脆弱なPHPを利用している場合、QUERY_STRING中の“_SERVER[“を遮断する。

その他に考慮できること

- Amazon Inspectorでの設定ミスの捜査(rootログイン許可や脆弱なミドルウェアバージョン、脆弱性の対応状況)
- Amazon InspectorでのCISベンチマークとの適合性チェック
- AWS ConfigやAmazon EC2 Systems Managerを用いた、システム構成変更の検出

#A6 – Sensitive Data Exposure

アプリケーションの欠陥による機密情報の暴露をWAFで緩和するのは難しい。
この欠陥には、一般に不完全に実装された暗号化が含まれる（弱い暗号の利用を許容していること）

AWS WAFとしては、HTTPリクエスト中の機密情報を識別するパターンをString-Match Conditionで検出することで、機密情報へのアクセスを検出することができる。（ホストするアプリケーションに対する深い知識が必要）
アプリケーションが、アップロードを許容する場合、Base64を示す文字列の一部を検出するString-Match Conditionが有効（BodyはBase64でエンコードされているから）
一般的ではない手法

その他に考慮できること

- AWS内の機能を使って、接続ポイントにて、ELBで強い暗号化suiteを使用するように制限する
- クラシックロードバランサの場合、事前定義・カスタムセキュリティポリシーで制御できる。
- アプリケーションロードバランサの場合、事前定義セキュリティポリシーで制御できる。
- Cloud Frontでも利用するSSLプロトコルを制限できる。

#A7 – Insufficient Attack Protection

2017年から新設
このカテゴリは、新しく発見された攻撃経路や異常なリクエストパターン、または発見されたアプリケーションの欠陥にタイムリーに対応する能力に重点を置いている。
幅広い攻撃ベクトルが含まれるので、他のカテゴリと重複する部分もある。

確認ポイント

- アプリケーションに対して、異常なリクエストパターンや大量通信を検出できるか？
- その検出を自動化できる仕組みはあるか？
- 不要な通信に対して、ブロックできる仕組みはあるか？
- 悪意のあるユーザーの攻撃開始を検出できるか？
- アプリケーションの脆弱性に対するパッチ適用までの時間はどの程度かかる？
- パッチ適用後の有効性を確認する仕組みはあるか？

AWS WAFで何ができるか

- Size-Content Conditionを使うことで、アプリケーションで利用するサイズ以上の通信を検出・遮断できる。
- URIやクエリ文字列のサイズを、アプリケーションにとって意味のある値に制限すること。
- RESTful API用のAPIキーなどの特定のヘッダーが必要になるようにすることもできる。
- 特定IPアドレスからの5分間隔での要求レートに対する閾値設定。(例えば、UserAgentとの組み合わせでのカウントも可能)
- Web ACLはプログラマブルで反映が早いのが利点(CloudFrontに対しても約1分で反映)
- ログの出力傾向から分析して、Web ACLを自動調整する機能も構築できる。

AWS WAFのセキュリティオートメーション機能の活用

- Lambdaを使って、4xxエラーを多く出しているIPアドレスを特定してIPブラックリストに登録する。
- 既知の攻撃者に対しては、外部ソースのIPブラックリストを活用する。
- ボットとスクレイバに対しては、robots.txtファイルの 'disallow'セクションにリストされている特定URLへのアクセスを行ったIPを、IPブラックリストに登録する。(ハニーポットと表現されています)

#A8 – Cross-Site Request Forgery

CSRFは、WebアプリケーションのStateを変更する機能を対象としている。
State変更に係るURLやフォーム送信などのHTTPリクエストを考慮する。
「ユーザーがその行動を取っている」ということを必ず証明する機構がなければ、悪意のあるユーザーによるリクエスト偽造を判断する方法はない。

- セッショントークンや送信元IPは偽造できるので、クライアント側の属性に頼るのは有効ではない。
- CSRFは、特定のアクションのすべての詳細が予測可能であるという事実（フォームフィールド、クエリ文字列パラメータ）を利用する。
- 攻撃は、クロスサイトスクリプティングやファイルインクルージョンなどの他の脆弱性を利用する方法で実行される。

CSRF攻撃への対処

- アクションをトリガーするHTTPリクエストに予測困難なトークンを含める
- ユーザー認証プロンプトの要求
- アクション要求時のキャプチャの提示

AWS WAFで何ができるか

- 固有トークンの存在確認
- 例えば、UUIDv4を活用して、x-csrf-tokenという名前のカスタムHTTPヘッダーの値を期待する場合は、Byte-Size Conditionが使える。
- ブロックルールには、POST HTTPリクエスト条件に加える

その他にできること

- 上記のようなルールでは、古い/無効な/盗まれた トークンの検出については、アプリケーションでの対応が必要
- 例えばの仕組み
- サーバが、一意のトークンを隠しフィールドとしてブラウザに送信し、ユーザーのフォーム送信時の期待値にする。
- 期待したトークンが含まれないPOSTリクエストを安全に破棄できる。
- 処理後のセッションストアからトークンは削除しておくことで、再利用がされないことを保証。

#A9 – Using Components with Known Vulnerabilities

既知の脆弱性を持つコンポーネントの利用
ソースや、商用/オープンソースのコンポーネント、フレームワークを最新に保つことが重要
最も簡単な攻撃ベクトルで、その他の攻撃手法の突破口にもなる。
脆弱なサブコンポーネントに依存するコンポーネントの利用しているケース。
コンポーネントの脆弱性は、CVEにて管理/追跡されないので、緩和が難しい。

- アプリケーション開発者は、それぞれのベンダー、作成者、またはプロバイダとのコンポーネントのステータスを個別に追跡する責任を負う。
- 脆弱性は、既存のバージョンを修正するのではなく、新機能を含む新しいバージョンのコンポーネントで解決される。
- そのため、アプリケーション開発者は、新バージョンの実装、テスト、デプロイの工数を負担する。

基本的な対処に

- アプリケーションの依存関係と基礎となるコンポーネントの依存関係の識別と追跡
- コンポーネントのセキュリティを追跡するための監視プロセス
- コンポーネントのパッチやリリース頻度、許容されるライセンスモデルを考慮したソフトウェア開発プロセスとポリシーの確立
- これらにより、コンポーネントプロバイダーがコード内の脆弱性に対処する際に、迅速に対応できる。

AWS WAFで何ができるか

- アプリケーションで使用していないコンポーネントの機能に対するHTTPリクエストをフィルタリングおよびブロックによる、攻撃面の削減
- 例）HTTPリクエストを直接/間接的にアセンブルするコードへのアクセスのブロックする
- String-matchコンディションを用いたURI検査（例えば、"/includes/"の制限）
- アプリケーションでサードパーティのコンポーネントを使用しているが機能のサブセットのみを使用する場合は、同様のAWS WAF条件を使って、使用しないコンポーネントの機能への公開URLパスをブロックする。

その他にできること

- ペネトレーションテスト。マーケットプレイスで買える。申請が必要だが、一部事前承認を受けているサービスでは申請が不要なこともある。(マーケットプレイス上のマークで識別可能)
- 展開とテストのプロセスに統合して、潜在的な脆弱性を検出するとともに、展開されたパッチが対象となるアプリケーションの問題を適切に緩和する。

#A10 – Underprotected APIs

2017年版の新カテゴリ
特定アプリケーションの欠陥パターンではなく、潜在的な攻撃ターゲットを示す

- UIを持たないアプリケーションは増えてきている。(UI/API両方使えるサービスも同様)
- 攻撃ベクトルは、A1-A9までと変わらないことが多い。
- APIはプログラムからのアクセスのために設計されているので、セキュリティテストでは、追加の考慮事項がある。
- APIは、(Rest,SOAP問わず)複雑なデータ構造での動作とより広い範囲の要求頻度と入力値を使用するように設計される事が多い。

AWS WAFでできること

- A1-A9での対応と変わらないが、対APIとして追加でできる事がある。
- 強化が必要な主要コンポーネントは、プロトコルパーサ自体(XML,YAML,JSON 等)
- パーサーの欠陥を悪用しようとする特定の入力パターンをString-match Condition、またはByte-Size Conditionを使用して、そのような要求パターンをブロックする。

# 旧OWASP Top10 A10 - Unvalidated Redirects and Forwards

リダイレクトや転送要求を検証しない場合、悪意のある当事者が正当なドメインを使用してユーザーを不要な宛先に誘導する可能性がある。

- 例）短縮URLを生成する機能がある場合、URLジェネレータがターゲットドメインを検証しないことで、悪意を持ったユーザーが正式サービス上から悪意のあるサイトへの短縮URLを発行できる。

AWS WAFでできること

- まず、アプリケーションでリダイレクトとフォワードがどこで発生するのかを理解する(リクエストパターン等)
- アプリケーションが使用する、サードパーティコンポーネントも同様にチェックする。
- エンドユーザからのHTTPリクエストに応じてリダイレクトと転送が生成された場合は、AWS WAFでリクエストをQUERY_STRINGやURIに対するString-Match Conditionでフィルタリングする（リダイレクト/転送の目的で信頼されているドメインのホワイトリストを維持する）

# Cloud Formationテンプレート

Web ACLと、このドキュメントで推奨されている条件タイプとルールを含むAWS CloudFormationテンプレートが用意されています。
今回は、解説を割愛します。

#所感
AWS WAFの設定は基本的にDIYですが、実装のポイントをOWASP Top10になぞらえて、その対応を解説する良いヒント集だと思いました。
AWS WAFを設定する人は、一読するのがいいですね。
外部にAWS WAFの設定を依頼する人は、アプリケーションの特性をよく理解している人を立てて、設定する人とよくコミュニケーションを取ることが重要だとわかります。
セキュリティ製品の真価を発揮するには、保護する対象のサービスへの理解とサービスへの適合化が必要なのは、どんなソリューションにも共通しますね。

今日はここまでです。
お疲れ様でした。