【目次】

  1. 1. はじめに
  2. 2. 調査に使用したJSONデータ
  3. 3. 調査を行ったルール条件
  4. 4. 調査した結果
  5. 5. おわりに

1. はじめに

最近、AWS WAF自体のバイパス方法についても研究が進んできており、2023年7月26日には無効なJSON形式の場合、JSON Bodyを検査するルールにてバイパスされるケースがあるという記事が公開されました。

AWS WAF Bypass: invalid JSON object and unicode escape sequences

本ブログ記事では、いくつか特定の条件をピックアップして実際の検知状況を確認した結果をまとめます。

JSON Bodyを検査対象としたルールを作成する方法については、以下のブログ記事をご参考ください。
JSON 形式のリクエストボディで 特定のキーや値を指定して AWS WAF で検知する方法

2. 調査に使用したJSONデータ

上記の記事では、JSONデータのキーが重複している場合にバイパスできる場合があるという記述がありました。
そのため、今回はキーの重複に加えて、AWS公式ドキュメントに有効なキーと値のペアとして解析可能と記載のあったデータを用いて調査を行いました。

1. カンマ不足:

{"key1":"value1""key2":"value2"}

2. コロン不足:

{"key1":"value1","key2""value2"}

3. 余分なコロン:

{"key1"::"value1","key2":"value2"}

4. 余分かつ不足するコロン:

{"key1"::"value1","key2""value2"}

5. キーの重複:

{"key1":"value1","key1":"value2"}

※AWS公式ドキュメント上では「余分なコロン: {"key1"::"value1","key2""value2"} 」と記載されていたため、本記事の調査では「3. 余分なコロン」と「4. 余分かつ不足するコロン」にわけています。

3. 調査を行ったルール条件

今回、検知状況を確認したルールの条件は以下の通りとなり、いずれも条件にマッチするとBLOCKするルールを設定しました。

なお、前提として、JSON Bodyを検査する際は [Inspect] にて [Body] を選択した上で、[Content type] にて [JSON] を選択する必要があります。
条件等の詳細については、AWS公式ドキュメントをご参考ください。
リクエストコンポーネントオプション(JSON本文)

ルール1. 値に「value1」を含む:
JSON match scope: All
How AWS WAF should handle the request if the JSON in the request body is invalid: None
Content to inspect: Full JSON content
Match type: Contains string
String to match: value1

ルール2. 値に「value2」を含む:
JSON match scope: All
How AWS WAF should handle the request if the JSON in the request body is invalid: None
Content to inspect: Full
Match type: Contains string
String to match: value2

ルール3. キー「key1」のみを検査対象とし、値のサイズが0を超える場合:
JSON match scope: All
How AWS WAF should handle the request if the JSON in the request body is invalid: None
Content to inspect: Only included elements
Included elements: /key1
Match type: Size greater than
Size in bytes: 0

ルール4. 値に「value2」を含み、無効なJSONの場合はマッチさせる:
JSON match scope: All
How AWS WAF should handle the request if the JSON in the request body is invalid: Match
Content to inspect: Full
Match type: Contains string
String to match: value2

ポイントとしては、ルール1から3は、いずれも「How AWS WAF should handle the request if the JSON in the request body is invalid」(JSONデータを解析できなかった場合の動作)が [None] となっており、解析エラーが発生する時点までのコンテンツが検査対象となります。
ルール1とルール2ではそれぞれ値を変更し、ルール3ではキーを指定した上で、値は0を超えるサイズとしました。

ルール4については、「How AWS WAF should handle the request if the JSON in the request body is invalid」は [Match] としており、解析エラーが発生したらマッチするような条件となっています。
それ以外の条件は、ルール2と同じです。

4. 調査した結果

結果は、以下の通りとなりました。

ルール 1. カンマ不足 2. コロン不足 3. 余分なコロン 4. 余分かつ不足するコロン 5. キーの重複
ルール1. 値に「value1」を含む 検知なし 検知あり 検知あり 検知あり 検知あり
ルール2. 値に「value2」を含む 検知なし 検知あり 検知あり 検知あり 検知なし
ルール3. キー「key1」のみを検査対象とし、値のサイズが0を超える場合 検知なし 検知あり 検知あり 検知あり 検知あり
ルール4. 値に「value2」を含み、無効なJSONの場合はマッチさせる 検知あり 検知あり 検知あり 検知あり 検知あり

上記調査結果から分かるポイントは以下3つです。

  • 1. 不正なJSONフォーマットであってもAWS WAFは可能な限り有効なものとして判定してくれる

    公式ドキュメントに記載のとおり、コロンが不足・重複しているなど一般的には正しいフォーマットではないJSON文字列であっても、ある程度有効なJSON文字列として解釈されることが確認できました。

  • 2. ただし、カンマ不足のものについては有効なものとして判定できていないように見える(今回の調査上は)

    カンマ不足のケースについては、公式ドキュメント上は有効なJSONとして解釈されるように読めましたが、今回の調査ではkeyの検査にせよvalueの検査にせよ、期待する検査結果となりませんでした。設定には注意が必要と思われます。

  • 3. キーが重複したJSONの場合、重複したキーより後段にあるキーと値のペアについては検査の対象とならない

    冒頭で紹介した記事に記載されていた「キーの重複」については、ルール2にて検知ができない結果となりました。
    キーが重複していたため、2つ目のキーと値のペアである "key1":"value2" については解析ができず、マッチしなかったのだと考えられます。

5. おわりに

調査した結果、JSON Bodyを扱うルールはかなり特徴のあるステートメントであり、JSONデータの形式によっては意図しない動作となることもありそうでした。
JSON Bodyを使ったルールを作成する際は、注意が必要かと思います。

また、AWS WAF の仕様に依存することにはなりますが、不完全なJSONについてはmatchとして扱い、そもそも受け付けないという選択肢も考えられます。

ルールアクションをCOUNTにて検知状況を把握することも可能ですので、AWS公式ドキュメントをしっかり読み込んだ上で、十分なテストを行ってから運用を開始されることをおすすめします。