Loading HuntDB...

Variant of CVE-2013-0269 (Denial of Service and Unsafe Object Creation Vulnerability in JSON)

Medium
R
Ruby
Submitted None
Reported by jeremyevans

Vulnerability Details

Technical details and impact analysis

Business Logic Errors
During my recent keyword argument separation work on `rb_scan_args` in the master branch, I discovered what I now think is a vulnerability. While the CVE-2013-0269 change fixed most usage of `JSON.parse`, it ended up not fixing `Kernel#JSON`. The reason behind this is that internally, in `JSON::Parser#initialize` (in `cParser_initialize` in `ext/json/parser/parser.c`), there is a separate branch taken depending on whether an option hash was provided. The fix for CVE-2013-026 only fixed one of these branches (when a option hash is provided). It did not fix the other branch (when no option hash is provided). `Kernel#JSON` is able to easily hit the case where no option hash is provided, because it does: ```ruby def JSON(object, *args) if object.respond_to? :to_str JSON.parse(object.to_str, args.first) ``` In the common case, no extra arguments are provided, and `args.first` is `nil`. Historically, Ruby has allowed the `rb_scan_args` `:` character to handle a `nil` option hash like no option hash was provided. This is deprecated in the master branch, and a warning is issued, but it is still supported. I fixed this in the master branch in the `rb_scan_args` commit, as it was needed to avoid the warning: https://github.com/ruby/ruby/commit/80b5a0ff2a7709367178f29d4ebe1c54122b1c27#diff-59fb0f5411be4c22009691e1a7f5a185 . It was only later, when I was going to report this issue upstream that I realized the security implications. I believe all previously released versions of Ruby since 1.9 (when JSON was included in stdlib) are vulnerable to this. I think this fix should be backported to Ruby 2.4, 2.5, and 2.6, and another CVE issued. In addition to `Kernel#JSON`, there are some other vulnerable calls, though they are likely to be less common. Full example code: ```ruby require 'json' class A < Struct.new(:a) def self.json_create(object) new(*object['args']) end def to_json(*args) { 'json_class' => self.class.name, 'args' => [ a ], }.to_json(*args) end end js = A.new(1).to_json p JSON.parse(js) #=> {"json_class"=>"A", "args"=>[1]} p JSON(js) #=> #<struct A a=1> # Also vulnerable, resulting in #<struct A a=1> p JSON.parse(js, nil) p JSON[js, nil] p JSON::Parser.new(js).parse ``` ## Impact This highly depends on the application using in question. In order to be vulnerable, `Kernel#JSON` or one of the other vulnerable calls must be called with user provided input. I am not sure this results in denial of service since Ruby 2.2, due to the support of dynamic symbols. However, I have not analyzed the related JSON code to determine if it creates dynamic or static symbols when `create_additions` is used. Assuming that `Kernel#JSON` is called with user-provided input, this allows creation of arbitrary objects where there is a named class that has a `json_create` singleton method.. More precisely, this allows calling `json_create` methods on any named constant with arbitrary arguments (assuming the constant returns a true value for `json_createable?`). Many Ruby applications use libraries that have objects in constants that support `method_missing` and could possibly be vulnerable. However, I have not done any research into possible exploitability, which is why I listed severity as Medium. If any `json/add/*` files have been required, this could possibly be very dangerous, as those can allow the creation of arbitrary core/stdlib objects. For example `json/add/ostruct` being required, when combined with this vulnerability, allows the creation of arbitrary objects that support attacker-defined methods with attacker-defined values of any type supported by JSON. `json/add/regexp` allows the creation of arbitrary Regexps which could easily lead to denial of service, and combined with a vulnerability in the regexp engine (Onigmo), could potentially lead to remote code execution.

Related CVEs

Associated Common Vulnerabilities and Exposures

The JSON gem before 1.5.5, 1.6.x before 1.6.8, and 1.7.x before 1.7.7 for Ruby allows remote attackers to cause a denial of service (resource consumption) or bypass the mass assignment protection mechanism via a crafted JSON document that triggers the creation of arbitrary Ruby symbols or certain internal objects, as …

Report Details

Additional information and metadata

State

Closed

Substate

Resolved

Bounty

$500.00

Submitted

Weakness

Business Logic Errors