Denial of Service and Unsafe Object Creation Vulnerability in JSON Gem
groups.google.com
groups.google.com
This seems like poor method naming; I would not intuitively understand that "load" is far more dangerous than "parse."
Why not deprecate these and do names like
JSON.load_trusted
JSON.load_untrusted
To further confuse things, JSON.load has the very useful property that you can pass it a String or an IO (e.g. from Rack::Request#body), whereas JSON.parse only accepts a String.
edit: the docs will soon contain a warning about JSON.load; see https://github.com/flori/json/blob/master/lib/json/common.rb
http://www.zweitag.de/en/blog/ruby-on-rails-vulnerable-to-ma...
<3<3<3<3
With love :-) Thomas
i just tried quoted_id and it works against mysql on 3.2.x as well. quoted_id is defined in abstract/quoting.rb and any adapter that forwards quotes to the superclass will use it.
"Since Ruby symbols are not garbage collected, this can result in a denial of service attack."
If you have a long running Ruby app,and it does not garbage collect symbols, then those symbols are... constants I guess?That survive till the app stops operating? So I guess the assumption is that no app should use too many symbols (and they don't use much memory anyway?)
Symbols in Ruby are atoms (the term "atom" spans languages), and GC/space issues plague any persistent term like an atom, in any language.
And thus I arrive at a key question: Does Ruby have something like `list_to_existing_atom', or some mechanism for telling if a symbol exists already? I see no analog to this, only the `ID2SYM' macro in the extensions API, and similar calls like String#to_sym.
Perhaps there is some way to clean up symbols after they are created. This to me would seem like the ideal route. It's good they've got a stop-gap fix by changing defaults, but it feels to me like they're punting here. Perhaps users who do [ab]use this feature also would not like DOS attacks?
I hope others who know more about Ruby extension development, and symbol management capabilities, can chime in on these questions.
however, on ruby trunk they added a method: rb_check_id which can be used to check if a string has been already symbolized (https://github.com/ruby/ruby/blob/trunk/parse.y#L10465). this means when these reflection methods get passed a string and it hasn't been symbolized they can bail out and not symbolize the string. (https://github.com/ruby/ruby/blob/trunk/object.c#L2073)
Indeed, when researching just now, I saw examples of people throwing strings at Module#const_defined?, which no doubt get converted to symbols straightaway.
So if you reference the symbol :foo, it will transparently get pinned in memory somewhere. Referencing :foo again will not allocate an additional object - the interpreter will just give you the existing symbol.
This is usually not an issue, because an application typically operates on a small, fixed set of known symbols. But if an attacker can generate arbitrary symbols (e.g. if you call .to_sym on user input), he can exhaust memory.
irb(main):001:0> require 'json/add/rails'
=> true
irb(main):002:0> class Foo
irb(main):003:1> end
=> nil
irb(main):004:0> Foo.json_create({"x" => "bar"})
=> #<Foo:0x007fc5f3149540>
https://github.com/search?q=require+%27json%2Fadd%2Frails%27...