Forum: Ruby on Rails Fixing code affected by Unsafe Object Creation Vulnerability in JSON

Posted by unknown (Guest)
on 2013-02-13 13:46
(Received via mailing list)
With the latest JSON gem 1.7.7, its breaking some of my code because I 
was
using:

 {"json_class":"SomeClass","foo":"bar"}

So the it doesn't recreate the "SomeClass" object back with the new gem
update, I can make it work by passing in  :create_additions => true but
that defeats the point of the update. The class has some attribute 
values
that are defined by the user's user_agent and cookie but in the code I
can't see a way to create new attribute by the user.

Simplified version of some of the code:

class SomeClass
  attr_accessor :name, :cookie, :user_agent

  def initialize(params)
    params = params.symbolize_keys
    ['name', 'coookie', 'user_agent'].each do |attr_name|
      self.send("#{attr_name}=", params[attr_name])
    end
  end

  def to_json(*a)
    {
      'json_class'  => self.class.name,
      'data'        => self.attributes
    }.to_json(*a)
  end

  def self.json_create(o)
    new(o['data'])
  end
end

What's the best way to make it work properly? Is it safe to leave it as 
it
is and pass in  :create_additions => true?
Posted by unknown (Guest)
on 2013-02-14 12:49
(Received via mailing list)
anyone?
Posted by Jordon Bedwell (Guest)
on 2013-02-14 12:53
(Received via mailing list)
On 02/14/2013 05:48 AM, devorums@gmail.com wrote:
>      is and pass in  :create_additions => true?
JSON#load instead of #parse.  Parse is safe, load is not.
Posted by forum mail (Guest)
on 2013-02-14 16:32
(Received via mailing list)
Hi Jordon,

Thanks for your reply!

Sorry forgot to mention I am using #parse but that doesn't make it safe.
This article shows how parse is used to take advantage of this issue:
http://www.zweitag.de/en/blog/ruby-on-rails-vulner...

I forgot to mention that I was doing something like this to convert back
the object (which is definitely not right in terms of security):

result = JSON.parse(object, create_additions: true)

Maybe the best option would be to stop serializing/deserializing classes 
in
general.
Posted by Jordon Bedwell (Guest)
on 2013-02-14 16:50
(Received via mailing list)
On 02/14/2013 09:30 AM, forum mail wrote:
> Sorry forgot to mention I am using #parse but that doesn't make it safe. This
> article shows how parse is used to take advantage of this issue:
> 
http://www.zweitag.de/en/blog/ruby-on-rails-vulner...

That article shows how parse /was/ used to inject, that was fixed, read
the security announcements and update your JSON if you still have that
problem.  Parse was never meant to act like that and it was an oversight
that was quickly fixed once noticed by somebody.

[10] pry(main)> class MyClass
[10] pry(main)*   def self.json_create(attributes)
[10] pry(main)*     new.tap do |instance|
[10] pry(main)*       attributes.each do |key, value|
[10] pry(main)*         instance.instance_variable_set(
[10] pry(main)*           "@#{key}", value
[10] pry(main)*         )
[10] pry(main)*       end
[10] pry(main)*     end
[10] pry(main)*   end
[10] pry(main)* end;

[12] pry(main)> JSON.parse '{
[12] pry(main)*   "json_class":"MyClass",
[12] pry(main)*   "name":"My name",
[12] pry(main)*   "title":"Me"
[12] pry(main)* }'
=> {"json_class"=>"MyClass", "name"=>"My name", "title"=>"Me"}

[13] pry(main)>
[14] pry(main)> JSON.load '{
[14] pry(main)*   "json_class":"MyClass",
[14] pry(main)*   "name":"My name",
[14] pry(main)*   "title":"Me"
[14] pry(main)* }'
=> #<MyClass:0x0000000284a6a0>


> Maybe the best option would be to stop serializing/deserializing classes in 
general.

It depends on what you are serializing it for but I'm not here to judge,
all I can say is most of the time for what people are doing it for I
would probably consider it a dumb ass thing to do, but we all do dumb
ass things so I can't really hate you or chastise you for it, only warn
that there are probably better ways to go about what you are doing, even
if it costs you more CPU time in terms of micro seconds that would
certainly be better.
Posted by forum mail (Guest)
on 2013-02-14 17:36
(Received via mailing list)
Sorry to bother you again about this, your example is great, that's what
I'd like to achieve.. It's old code that I'm trying to maintain.

However when running it locally in a console I get the following:


Loading development environment (Rails 3.2.11)
1.9.3p194 :001 >  class MyClass
1.9.3p194 :002?>      def self.json_create(attributes)
1.9.3p194 :003?>          new.tap do |instance|
1.9.3p194 :004 >                attributes.each do |key, value|
1.9.3p194 :005 >                    instance.instance_variable_set(
1.9.3p194 :006 >                        "@#{key}", value
1.9.3p194 :007?>                    )
1.9.3p194 :008?>                end
1.9.3p194 :009?>            end
1.9.3p194 :010?>        end
1.9.3p194 :011?>    end;


1.9.3p194 :013 >    JSON.parse '{
1.9.3p194 :014'>    "json_class":"MyClass",
1.9.3p194 :015'>    "name":"My name",
1.9.3p194 :016'>    "title":"Me"
1.9.3p194 :017'>  }'
 => {"json_class"=>"MyClass", "name"=>"My name", "title"=>"Me"}

1.9.3p194 :018 >  JSON.load '{
1.9.3p194 :019'>    "json_class":"MyClass",
1.9.3p194 :020'>    "name":"My name",
1.9.3p194 :021'>    "title":"Me"
1.9.3p194 :022'>  }'
 => {"json_class"=>"MyClass", "name"=>"My name", "title"=>"Me"}
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.