4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JSON Threat Protection Pluginで想定外のリクエストを抑止する

4
Last updated at Posted at 2025-12-12

本記事は「Kong Advent Calendar 2025」の13日目のエントリとして、JSON Threat Protection Pluginについて解説する。

先日、AI関連の論文プラットフォーム「OpenReview」において、BOLA (Broken Object Level Authorization) に起因する深刻な脆弱性が報告された
非公開Group IDの悪用により不正アクセスが可能だったこの事例は、APIセキュリティの重要性を改めて浮き彫りにした。

API保護には多層的な対策が必要となるが、今回はその基礎となる「入力データの構造検証」に焦点を当てる。
Kong GatewayのJSON Threat Protection Pluginを利用し、肥大化したペイロードや深いネストなど、システムに負荷を与える不正なJSONリクエストを検知・遮断する方法について解説する。

JSON Threat Protection Pluginとは

JSON Threat Protection Pluginは、設定されたポリシーと照らし合わせて、JSONリクエストの構造を検証するKong Gatewayのプラグインである。
以下の特徴がある。

  • 違反ポリシーと合致した場合、ブロックするかログに残すだけにするかの2種類が選択できる
  • 対象リクエストのメソッドはPOST、PUT、PATCHに限定される
  • ポリシーで設定できる項目は以下
    • JSONオブジェクトの深度
    • 配列要素の最大数
    • オブジェクトエントリの最大数
    • オブジェクトキーの最大数
    • 文字列の最大数
    • ボディのサイズ

イメージ的にはJSONの以下のようなところをチェックしてガードする感じ。
20251209162410.png

このように、ペイロードの中身を検証するようなことは出来ないが、JSONの構造から攻撃を検知することが出来るようになっている。

具体的な設定値は以下となる。

パラメータ デフォルト値 説明
allow_duplicate_object_entry_name boolean true JSONオブジェクト内でキーの重複を許可するかどうか
enforcement_mode string block セキュリティポリシーの適用モードを指定
block: 違反したリクエストを遮断
log_only: 遮断はせず、ログ出力のみ実施
error_message string Bad Request 問題検出時のクライアントへ返すエラーメッセージを指定
error_status_code integer 400 問題検出時のクライアントへ返すHTTPステータスコードを指定(400~499の範囲)。
max_array_element_count integer -1 配列に含まれる要素数の最大値を指定。(-1 は無制限)
max_body_size integer 8192 リクエストボディの最大サイズ(バイト数)を指定。(-1 は無制限)
max_container_depth integer -1 オブジェクトや配列のネスト(入れ子)の深さの最大値を指定。(-1 は無制限)
max_object_entry_count integer -1 1つのオブジェクトに含まれるエントリ(キーと値のペア)の最大数を指定。(-1 は無制限)
max_object_entry_name_length integer -1 オブジェクトのキー(エントリ名)の最大文字数を指定。(-1 は無制限)
max_string_value_length integer -1 文字列の値の最大文字数を指定。(-1 は無制限)

検証

ここでは以下のデータをPOSTして、JSON Threat Protection Pluginが正しく動作するか確認する。

{
  "account": "ipppppei",                    
  "age": 18,                                 
  "favorite": ["sake", "beer", "whisky", "rum"], 
  "address": {
    "street": "1-2-3",
    "city": "Tokyo",                      
    "country": {
      "name": "Japan",              
      "code": "+81"                    
    },
    "postal": "1234567"
  },
  "extra_field": "1234567890"
}

Kong Gatewayでは以下の設定をdeckで適用している。

_format_version: "3.0"
services:
- host: httpbin.konghq.com
  name: httpbin-service
  path: /
  port: 443
  protocol: https
  routes:
  - name: httpbin-route
    paths:
    - /httpbin
    plugins:
    - config:
        max_array_element_count: 3
        max_container_depth: 2
        max_object_entry_count: 5
        max_object_entry_name_length: 10
        max_string_value_length: 9
      enabled: true
      name: json-threat-protection

投げるJSONについては以下の点でポリシー違反が発生する。

  • max_array_element_count: favorite配列の要素数が4でポリシー違反
  • max_container_depth: address.countryオブジェクトが深さ3でポリシー違反
  • max_object_entry_count: addressオブジェクトのエントリ数が6でポリシー違反
  • max_object_entry_name_length: extra_fieldキーの文字数が11でポリシー違反
  • max_string_value_length: extra_fieldの値が10でポリシー違反

確認してみる。
まずJSONデータを環境変数に設定する。

export MY_JSON_DATA='{
  "account": "ipppppei",
  "age": 18,
  "favorite": ["sake", "beer", "whisky", "rum"],
  "address": {
    "street": "1-2-3",
    "city": "Tokyo",
    "country": {
      "name": "Japan",
      "code": "+81"
    },
    "postal": "1234567"
  },
  "extra_field": "1234567890"
}'

リクエストを発行する。

curl -X POST http://localhost:8000/httpbin/post \
  -H "Content-Type: application/json" \
  -d "$MY_JSON_DATA" -i

するとHTTP/1.1 400 Bad Requestと共に以下のエラーメッセージが確認できる。

{
  "message":"Bad Request",
  "request_id":"592a9e699e44b713bbf88649e0d6c64a"
}

プラグインは正常に動作しており、ポリシー違反のリクエストが遮断されたことが分かる。
具体的にどのようなポリシー違反だったかはKongのエラーログを確認することで分かる。

2025/12/11 23:18:51 [warn] 2631#0: *109862 [kong] handler.lua:87 [json-threat-protection] JSON validate failed: at [$.favorite]: The maximum number of elements allowed in an array is exceeded., client: 172.18.0.1, server: kong, request: "POST /httpbin/post HTTP/1.1", host: "localhost:8000", request_id: "1e5a8223f2e072366417bf234edfc375"

エラーは1つだけでfavoritemax_array_element_countに違反していることが分かる。
他のポリシー違反についてはログ出力されていないため、1つ違反を検知するとその時点で処理を中断していると思われる。
またリクエストに応答するエラーメッセージに含まないのは攻撃者にヒントを与えないためであり、エラーの内容をクライアント側に伝えることは出来ない。

再度検証する。
favorite配列の要素数を3に減らして再度リクエストを発行すると、以下のエラーメッセージに変化した。

2025/12/11 23:21:33 [warn] 2632#0: *109865 [kong] handler.lua:87 [json-threat-protection] JSON validate failed: at [$.address.country]: The maximum allowed nested depth is exceeded., client: 172.18.0.1, server: kong, request: "POST /httpbin/post HTTP/1.1", host: "localhost:8000", request_id: "2ac5ba47c3935001b1a7700a7ff68872"

今度はaddress.countrymax_container_depthに違反していることが分かる。
address.countryオブジェクトを削除して再度リクエストを発行すると、以下のエラーメッセージに変化した。

2025/12/11 23:26:09 [warn] 2633#0: *109873 [kong] handler.lua:87 [json-threat-protection] JSON validate failed: at [$.extra_field]: The maximum string length allowed in an object's entry name is exceeded., client: 172.18.0.1, server: kong, request: "POST /httpbin/post HTTP/1.1", host: "localhost:8000", request_id: "d5706f248f2405125bd948487f609948"

extra_fieldの値がmax_object_entry_name_lengthに違反していることが分かる。
extra_fieldキーをextrafieldに変更して再度リクエストを発行すると、以下のエラーメッセージに変化した。

2025/12/11 23:36:32 [warn] 2630#0: *110918 [kong] handler.lua:87 [json-threat-protection] JSON validate failed: at [$.extrafield]: The maximum length allowed for a string value is exceeded., client: 172.18.0.1, server: kong, request: "POST /httpbin/post HTTP/1.1", host: "localhost:8000", request_id: "f15bb6406ee3de422904484a91709e79"

今度はextrafieldの値がmax_string_value_lengthに違反していることが分かる。
最後にextrafieldキーと値を以下のように修正してリクエストを発行する。

export MY_JSON_DATA='{
  "account": "ipppppei",
  "age": 18,
  "favorite": ["sake", "beer", "whisky"],
  "address": {
    "street": "1-2-3",
    "city": "Tokyo",
    "postal": "1234567"
  },
  "extrafield": "123456789"
}'

するとHTTP/1.1 200 OKが返ってリクエストが正常に通る。
以上より、JSON Threat Protection Pluginが正しく動作していることが確認できた。

まとめ

今回はKong GatewayのJSON Threat Protection Pluginを利用して、JSONリクエストの構造を検証し、想定外のリクエストを抑止する方法について確認した。
APIセキュリティの基礎として、JSONリクエストの構造検証は潜在的な攻撃からAPIを保護する有効な手段となると思う。
特定の攻撃方法に対する防御策ではないが、漠然とAPIセキュリティを気にしている人はJSON Threat Protection Pluginの導入を検討するとよいと思う。

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?