リクエスト JSON Body 内の特定のキー値のみ WAF ルール評価対象外に設定したい

リクエストの JSON body 内の特定の要素にインジェクション攻撃に該当する文字列があった際に、SQL データベースマネージドルールグループ(AWSManagedRulesSQLiRuleSet) でブロックされないようにしたい場合、その他の JSON Body 要素のみを評価するよう設定することで対応可能です。
2024.05.07

困っていた内容

SQL インジェクション防止のため、WAF WebACL に AWS マネージドルールグループ AWSManagedRulesSQLiRuleSet を追加しています。

リクエストの JSON Body は以下の形式ですが、"others" の値がこのルールに抵触しブロックされることがあります。

{ "userid" : "testuser", "password" : "testpasss", "others" : "something"}

"others" の値は評価せず、SQL インジェクションに該当する文字列であってもブロックしないようにルールを設定したいのですが、設定方法を教えてください。

どう対応すればいいの?

特定の JSON body 要素のみ評価除外するような設定はできませんが、評価を行う対象の JSON Body 要素を指定することは可能です。

以下の手順で、"others" 以外の JSON Body 要素 ("userid"、"password") の値のみ評価するようルールを設定します。

  1. マネージドルールグループ AWSManagedRulesSQLiRuleSet で SQLi_BODY を Override: Count に設定します。
  2. JSON Body 内 "userid"、"password"の値のみ、SQL injection attacks に該当するか評価するカスタムルールを追加します。

以下に詳細を説明します。

手順 1: マネージドルールグループ AWSManagedRulesSQLiRuleSet で SQLi_BODY を Override: Count に設定します。

手順 2: JSON BODY 内 "userid"、"password"の値のみ、SQL injection attacks に該当するか評価するカスタムルールを追加します。

以下の設定でカスタマーマネージドルールを作成し、追加します。

  • If a request: matches the statement
  • Inspect: Body
  • Content type: JSON
  • JSON match scope: Values
  • How AWS WAF should handle the request if the JSON in the request body is invalid: < ご要件応じて選択 >
  • Content to inspect: Only elements
  • Included elements:
    • /userid
    • /password
  • Match type: Contains SQL injection attacks
  • Text transformation: None
  • Oversize handling: Continue
  • Sensitivity Level: Low
  • Action: Block

検証結果

インジェクションと判定される文字列 ' OR 'A' = 'A を使用してテストしてみます。

  1. userid の値を ' OR 'A' = 'A にしてリクエストを送信

    $ curl \
        -X POST \
        -H "Content-Type: application/json" \
        -d "{ \
            \"userid\" : \"' OR 'A' = 'A\", \
            \"password\" : \"testpasss\", \
            \"others\" : \"something\"}" \
        https://xxxxxx.com/apitest1
    {"message":"Forbidden"}

    アクセスが拒否されました。

  2. password の値を ' OR 'A' = 'A にしてリクエストを送信

    $ curl \
        -X POST \
        -H "Content-Type: application/json" \
        -d "{ \
            \"userid\" : \"testuser1\", \
            \"password\" : \"' OR 'A' = 'A\", \
            \"others\" : \"something\"}" \
        https://xxxxxx.com/apitest1
    {"message":"Forbidden"}

    アクセスが拒否されました。

  3. others の値を ' OR 'A' = 'A にしてリクエストを送信

    $ curl \
        -X POST \
        -H "Content-Type: application/json" \
        -d "{ \
            \"userid\" : \"testuser1\", \
            \"password\" : \"testpasss\", \
            \"others\" : \"' OR 'A' = 'A\"}" \
        https://xxxxxx.com/apitest1
    "Hello world!!"%

    問題なくアクセスできました。

参考資料