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

There is a denial of service and unsafe object creation vulnerability in the json bundled with ruby. This vulnerability has been assigned the CVE identifier CVE-2013-0269. We strongly recommend to upgrade ruby.

Details

When parsing certain JSON documents, the JSON gem (includes bundled with ruby) can be coerced in to creating Ruby symbols in a target system. Since Ruby symbols are not garbage collected, this can result in a denial of service attack.

The same technique can be used to create objects in a target system that act like internal objects. These "act alike" objects can be used to bypass certain security mechanisms and can be used as a spring board for SQL injection attacks in Ruby on Rails.

Impacted code looks like this:

JSON.parse(user_input)

Where the `user_input` variable will have a JSON document like this:

{"json_class":"foo"}

The JSON gem will attempt to look up the constant "foo". Looking up this constant will create a symbol.

In JSON version 1.7.x, objects with arbitrary attributes can be created using JSON documents like this:

{"json_class":"JSON::GenericObject","foo":"bar"}

This document will result in an instance of JSON::GenericObject, with the attribute "foo" that has the value "bar". Instantiating these objects will result in arbitrary symbol creation and in some cases can be used to bypass security measures.

PLEASE NOTE: this behavior does not change when using `JSON.load`. `JSON.load` should never be given input from unknown sources. If you are processing JSON from an unknown source, always use `JSON.parse`.

All users running an affected release should either upgrade or use one of the workarounds immediately.

Workarounds

For users that cannot upgrade ruby or JSON gem, change your code from this:

JSON.parse(json)

To this:

JSON.parse(json, :create_additions => false)

If you cannot change the usage of `JSON.parse` (for example you're using a gem which depends on `JSON.parse` like multi_json), then apply this monkey patch:

module JSON
  class << self
    alias :old_parse :parse
    def parse(json, args = {})
      args[:create_additions] = false
      old_parse(json, args)
    end
  end
end

Affected versions

  • All ruby 1.9 versions prior to ruby 1.9.3 patchlevel 392
  • All ruby 2.0 versions prior to ruby 2.0.0 patchlevel 0
  • prior to trunk revision 39208

Credits

A huge thanks goes to the following people for responsibly disclosing this issue and working with the Rails team to get it fixed:

  • Thomas Hollstegge of Zweitag (www.zweitag.de)
  • Ben Murphy

History

  • Originally published at 2013-02-22 12:00:00 (UTC)