OWASP
OWASP - Open Web Application Security Project とは、Webをはじめとするソフトウェアのセキュリティ環境の現状、またセキュアなソフトウェア開発を促進する技術・プロセスに関する情報共有と普及啓発を目的としたプロフェッショナルの集まる、オープンソース・ソフトウェアコミュニティです。
OWASP Top 10 とは「もっとも重大なウェブアプリケーションリスクトップ 10」のことであり, Web 界隈のセキュリティ対策基準のデファクトスタンダードとのこと.
AWS WAF には OWASP Top 10 に記されたリスクを軽減するためのテンプレートが用意されているため,内容を確認して手元の環境で試してみる.
AWS WAF OWASP Top 10 テンプレート
実際の OWASP Top 10 からは項目が調整されている.
- Use AWS WAF to Mitigate OWASP’s Top 10 Web Application Vulnerabilities
- 忙しい人のための Use AWS WAF to Mitigate OWASP’s Top 10 Web Application Vulnerabilities メモ - Qiita
CloudFront + WAF で対策できることは限られてくるため, Origin (Web サーバやフレームワーク) 側でもしっかり対策するようにと書いてある.
A1 – Injection
単にインジェクションと書いてあるが,実際は SQL インジェクションのこと.
WAF だけで攻撃を防ぐのは難しいためアプリケーション側でも対策が求められる.テンプレートには下記のルールが含まれている.
- Body contains SQL injection threat after decoding as HTML tags
- Body contains SQL injection threat after decoding as URL
- 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
- Query string contains SQL injection threat after decoding as URL
- URI contains SQL injection threat after decoding as HTML tags
- URI contains SQL injection threat after decoding as URL
ボディがバイナリにシリアライズされている場合はボディの検証はサーバサイドプログラムで行う必要がある. WAF はバイナリを読めないためである.
システムがユーザに対してリクエストでクエリを送信することを許可している場合はルールの見直しが必要となる.特定の URL をルールから除外してクエリを通過させるように設定する方法がある.
A2 – Broken Authentication and Session Management
期限切れの認証情報をアプリ側で検出し,その情報を WAF に String Match で登録する.
- Header ‘cookie’ contains: “example-session-id” after decoding as URL
- Header ‘authorization’ ends with: “.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ” after decoding as URL
WAF の機能にあわせてサーバサイドプログラムの作り込みが必要となる.
サーバサイドで検知した情報を WAF に登録するか,検知した情報を用いてサーバサイドがブロックする (WAF を使わない) ように作り込むか,二択になると思われる.
A3 – Cross-Site Scripting (XSS)
インジェクションと同様.テンプレートには以下のルールが含まれている.
- Body contains a cross-site scripting threat after decoding as HTML tags
- Body contains a cross-site scripting threat after decoding as URL
- Header ‘cookie’ 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
- Query string contains a cross-site scripting threat after decoding as URL
- URI contains a cross-site scripting threat after decoding as HTML tags
- URI contains a cross-site scripting threat after decoding as URL
例によってシリアライズするならボディの検証はサーバサイドプログラムで行う必要がある.
CMS のエディタのようにリクエストに大量の HTML タグを含む場合や, SVG のように大量の <script>
タグを含む場合は除外ルールを作成する必要がある.
A4 – Broken Access Control
認証ユーザに本来付与されるはずの権限の範囲を超えた操作ができてしまう問題.
例えば,ユーザ ID 3324 のユーザが https://example.com/edit/profile?user_id=3324 にアクセスして自身の設定を変更できることは正常だが,ユーザ ID 3324 のユーザが https://example.com/edit/profile?user_id=3325 にアクセスしてユーザ ID 3325 のユーザの設定を変更できては問題となる.
テンプレートでは次のようにディレクトリトラバーサル対策が行われている.
- 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
A5 – Security Misconfiguration
開発環境の設定で本番環境を動かしてしまうようなミス.
- Apache を
ServerTokens Full
で動かしてしまう - directory listing を有効化してしまう
- エラー時のスタックトレースをユーザの画面に出力してしまう
Origin ありきで対策する必要がある.例えば WordPress であれば /wp-admin/ 以下のパスには特定の IP アドレスからのアクセスしか許可しないなど.また,使用しているサーバやフレームワークの脆弱性情報をキャッチアップして適切に対策を取ることが求められる.
テンプレートに仕込まれたルールは以下の通り.
- URI starts with: “/admin” after decoding as URL
- When a request does not originate from an IP address in 127.0.0.1/32
A6 – Sensitive Data Exposure
秘匿すべきデータが「入手しようと思えば入手できる」状態になっている問題.
https://qiita.com/fnifni/items/0ef1434f3fb5063d13e4#a6--sensitive-data-exposure
A7 – Insufficient Attack Protection
既知・未知の攻撃の検知や防御をリアルタイムに行えるかどうか.項目を一つにまとめるには守備範囲が広すぎるように思われる.
https://qiita.com/fnifni/items/0ef1434f3fb5063d13e4#a7--insufficient-attack-protection
テンプレートでは下記条件に一つでもマッチするとブロックするようになっている.誤検知が発生しやすいルールのため検証が求められる.
- The length of the URI is greater than 512
- The length of the Body is greater than 4096
- The length of the Query string is greater than 1024
- The length of the Header ‘cookie’ is greater than 4093
A8 – Cross-Site Request Forgery (CSRF)
https://qiita.com/fnifni/items/0ef1434f3fb5063d13e4#a8--cross-site-request-forgery
テンプレートのルールは以下の通り.
- HTTP method matches exactly to: “post” after converting to lowercase
- The length of the Header ‘x-csrf-token’ is equal to 36
ヘッダ x-csrf-token の長さに 36 を指定しているは UUID を想定しているためである.
A9 – Using Components with Known Vulnerabilities
各種コンポーネント (フレームワークやライブラリなど) の脆弱性対策は各自で責任を持って実施する必要がある.こちらも範囲が広いため A7 と被る部分がある.
Origin による部分が大きいため WAF テンプレートには対応ルールがない.各自が脆弱性のある機能や使われていない機能へのパスを文字列マッチングで URI フィルタリングしてブロックする程度となる.
A10 – Underprotected APIs
Origin が Web アプリというよりは API の場合の話である. API でも基本的には Web アプリと同様に A1 - A9 の対策を行えばよい.一方で, API はプログラムからアクセスされることを前提とした設計になっているため, UI を持つ Web アプリよりも考慮すべきことは多くなる (アクセス頻度が高い,より複雑なデータ構造を扱う,など).
WAF テンプレートには対応ルールがないが,むしろ A1 - A9 をそのまま適用できると考えた方がよいかもしれない.
標準的なプロトコルを用いている場合,どんなパーサが使われているか推測することは容易い (SOAP なら XML, RESTful なら JSON といった具合).よって,パーサの脆弱性を突くような攻撃は文字列マッチングやバイトサイズによってフィルタリングすることが望ましい.
テンプレートを試す
手元の Web アプリの開発環境の前段に WAF テンプレートを仕込み,どのリクエストがルールに抵触するか軽く確認した.
結果
A5 – Security Misconfiguration
管理画面のパスが /admin/ のため抵触する.また, IP アドレスも抵触する.
- URI starts with: “/admin” after decoding as URL
- When a request does not originate from an IP address in 127.0.0.1/32
A8 – Cross-Site Request Forgery (CSRF)
POST メソッドのリクエストのいくつかが CSRF 検知 (A8) の対象となった. CSRF 対策用のリクエストヘッダ X-CSRF-TOKEN が存在しないことが原因の模様.