top of page
IMG_0546.JPG

RailsのJSON処理に潜む罠:”_jsonジャグリング攻撃”とは?:

  • 執筆者の写真: 晋次 宮田
    晋次 宮田
  • 2025年2月5日
  • 読了時間: 3分

Railsの「_jsonジャグリング攻撃」とは?


はじめに


Ruby on Rails(以下、Rails)を使ったWebアプリ開発では、JSONデータをやり取りすることが一般的です。しかし、このデータ処理の仕組みを悪用した「_jsonジャグリング攻撃」という新しい手法が報告されています。(2024年12月報告)

この攻撃は、適切な対策をしていないと認可バイパス(アクセス制限の突破)や意図しない操作の実行を引き起こす可能性があります。

今回は

  • _jsonジャグリング攻撃とは何か?

  • どのような影響があるのか?

  • 具体的な攻撃のコード例

  • Railsでできる対策方法

について解説していきます。



_jsonジャグリング攻撃とは?


RailsのJSONパラメータ処理の仕組み

Railsでは、ユーザーから送信されたJSONデータをハッシュ(キーと値のセット)として扱います。通常、Railsのparamsオブジェクトは、送られたデータを自動的に解析して適切な型に変換します。しかし、データの形式によっては意図しない変換が発生する可能性があります。しかし、

  • 配列([1, 2, 3])

  • 文字列("hello") が送られてきた場合、自動的に _json というキーを持つハッシュに変換されます。


RailsがJSONをどのように処理するか?


ケース1:ハッシュが送信された場合(問題なし)

ユーザーが以下のようなデータを送信したとします:

{
  "name": "Taro",
  "age": 25
}

Railsのparamsオブジェクトではこのように処理されます:

params[:name] # => "Taro"
params[:age]  # => 25

ケース2:配列が送信された場合(Railsが自動変換)

ユーザーが 配列 を送信すると

["apple", "banana", "cherry"]

Railsでは次のように処理されます

params[:_json] # => ["apple", "banana", "cherry"]

配列が _json というキーのハッシュに変換されます。

ケース3:文字列が送信された場合(Railsが自動変換)

ユーザーが文字列を送信すると

"Hello, Rails!"

Railsでは次のように処理されます

params[:_json] # => "Hello, Rails!"

文字列も _json というキーのハッシュに変換されます。

実際の攻撃手法:認可バイパスの可能性

このRailsの仕様を悪用すると、本来許可されていない操作を実行できる可能性があります。

例えば、Railsアプリが単一IDの削除と 複数IDの削除を処理できるAPIを持っているとします。

攻撃コード例

通常、単一のIDを削除するAPI

{"id": 123}

複数のIDを削除するAPI

[456, 789]

このアプリでは、単一削除は管理者のみ実行できるが、複数削除は一般ユーザーも実行可能という仕様だったとします。

攻撃者が次のJSONを送るとどうなるでしょう?

{
  "id": 123,
  "_json": [456, 789]
}

Railsが処理すると:

params[:id]   # => 123
params[:_json] # => [456, 789]

この結果、認可のチェックでは id(123)のみ確認され、本来削除権限のない _json キーのデータ(456, 789)が意図せず処理される可能性があります。これは、Railsのパラメータ処理の仕様によるものであり、適切なバリデーションを行わないと攻撃者に悪用される恐れがあります。

Railsでの対策方法

Railsアプリケーションを安全に保つためには、以下の方法で意図しないJSONの処理を防ぐ必要があります。

1.そもそも_jsonキーが含まれるリクエストを拒否する

before_action :reject_invalid_json

def reject_invalid_json
  if params.has_key?(:_json)
    render json: { error: "Invalid JSON format" }, status: :unprocessable_entity
  end
end

2. Strong Parametersを活用する

params.require(:user).permit(:name, :email, :age)

意図しないパラメータ(_jsonなど)を受け取らないようにする。

3. JSONスキーマをバリデーションする(json-schema gemを活用)

require 'json-schema'

def validate_json_schema
  schema = {
    "type" => "object",
    "required" => ["user"],
    "properties" => {
      "user" => { "type" => "object" }
    }
  }

  unless JSON::Validator.validate(schema, params.to_unsafe_h)
    render json: { error: "Invalid JSON format" }, status: :unprocessable_entity
  end
end

まとめ:Rails開発者がすぐにできる対策

✅ _jsonキーを拒否する ✅ Strong Parametersで余計なデータを排除 ✅ JSONスキーマを定義してバリデーション

脅威のレベルとしてはSQLインジェクションなどのクリティカルなものと比べたら低いですが、上記事例の様なこともありうるのと、QAチームが画面上から気づくことは難しく、コードレビュー時でないと気づきにくい脅威ではあるため、頭の片隅に置いておくと良いと思います。

参考サイト

 
 
bottom of page