Live data from Hacker News

SQL Injection Vulnerability in Ruby on Rails; affects all versions

groups.google.com

61–70 of 220 posts

Re: SQL Injection Vulnerability in Ruby on Rails; affects all versions

#61
post #5

I am mostly a Django programmer so excuse my ignorance of rails. How does this keep happening? In Django you would do: Post.objects.get(pk=request.GET['id']) There really is no way to do SQL injection this way. This line in rails looks almost exactly like how you would do it in Django: Post.find_by_id(params[:id]) Also this seems really serious. It's not like a edge case where you need to grab a post by id. This is p…

You are going to have problems with this whenever you are composing SQL statement with any type of user-provided data as part of the raw SQL string passed to the server. This generally happens in one of two says: 1) (most common) You have a SQL statement that takes a user-provided parameter and you compose your SQL statement as a string, including that parameter (eg., sql = "SELECT * FROM person where id = " + form.i…

This is not the problem. Please stop spreading misinformation.

ActiveRecord does escape user input.

The exploit here is that under certain obscure circumstances it is possible trick ActiveRecord into thinking the user input is an options hash passed by the caller.

From my understanding this is non-trivial to exploit on most applications, and requires passing in a Hash with symbol keys.

This is still a vulnerability that needs to be (and has been) fixed, but it is nowhere near as stupidly obvious as you are claiming.

Re: SQL Injection Vulnerability in Ruby on Rails; affects all versions

#63
post #27

Earlier quoted context omitted.

In Python, the parameter escaping is done at the level of the database driver not the ORM. Isn't this the case with Ruby? Of course, you could use the driver incorrectly to risk SQL injection, but that is a very obvious mistake that no experienced developer would make.

the ORM escapes the parameter but it lets you specify bits of SQL by hand (think "select foo, myfunc(bar) as BAZ, joineds.quux as quux"). In theory when you do that you have already given up on letting the framework handle it for you, and you must take care of not feeding raw user input as the select code, for example. The issue here is that the option to do this is exposed in a functionality where people do not expe…

Well, the Django ORM also allows you to write SQL by hand and if you make a mistake you can fall pray to SQL injection, so I'm assuming that there's something different about this exploit. From what I understand the current issue appears because the person who implemented the faulty method uses SQL directly and doesn't pass the parameters separately.

In Python, you would do something like this:

    execute('select name, age from employees where id=?', (params['id'],))
This passes the id as the second argument to the execute function. If you do this, on the other hand, you open yourself to SQL injection, because %s is replaced with params[id] and no escaping is done:

    execute('select name, age from employees where id=%s' % params['id'])

Re: SQL Injection Vulnerability in Ruby on Rails; affects all versions

#64

Does something similar affect mongodb or am I OK?

Depending on your ODM, similar vulnerabilities may exist. For example, if you have a user finder that expects an ID parameter

    id=1
    User.where(:id => params[:id]).first
    User.where(:id => 1).first
Then I could construct a hash in the param:

    id[$gt]=0
This would perform the following find:

    User.where(:id => params[:id]).first
    User.where(:id => {"$gt" => 0}).first
Which will return the first user record (probably).

You should be performing casts (usually to strings) before you pass your data to your ODM.

    id[$gt]=0
    User.where(:id => params[:id].to_s).first
    User.where(:id => "{:$gt=>0}").first
This will correctly fail to a find a document.

Re: SQL Injection Vulnerability in Ruby on Rails; affects all versions

#65

Would appreciate if someone could explain the issue in a little more detail for non RoR developers

Assuming you have no ruby knowledge:

ActiveRecord (rails' default ORM) has a feature called "dynamic finders". When you call a method like `Forum.find_by_url('news.ycombinator.org')` it gets a first forum with such url. This is a sugar over `Forum.where(:url => 'news.ycombinator.org').first`.

Normally, you use it like that `Forum.find_by_url(params[:url])` where `params` is a hash of parameters (that is auto-generated from http get/post params). What happens if instead of "normal" value like "news.ycombinator.org" you pass a hash?

    1.9.3p327 :018 > Forum.find_by_id({:select => 'id FROM forums --'})
    Forum Load (0.5ms)  SELECT id FROM forums -- FROM `forums` WHERE `forums`.`id` IS NULL LIMIT 1
Uh-oh.

However, not everything is lost. Rails params are converted to a special hash class. It's called HashWithIndifferentAccess, because you can access its values by string keys and symbol keys likewise. So that

    h = {:a => 1, "b" => 2}.with_indifferent_access
    h["a"] # => 1
    h[:a]  # => 1
    h["b"] # => 2
    h[:b]  # => 2
What happens if we pass user-generated params? It seems like not much:

    1.9.3p327 :024 > Forum.find_by_id({:select => 'id FROM forums --'}.with_indifferent_access)
    ArgumentError: Unknown key: select
So I guess they are erring on a safe side here.

Re: SQL Injection Vulnerability in Ruby on Rails; affects all versions

#66
post #62

Does something similar affect mongodb or am I OK?

This is an ActiveRecord issue...MongoDB uses its own ORM (Mongoid/Mongomapper)

That's what I was referring to. Do mongomapper and mongoid have this problem?

Re: SQL Injection Vulnerability in Ruby on Rails; affects all versions

#67

It seems like this is being conflated with the session token issue? How do you submit params with symbolized keys? Hashes are easy enough, but it doesn't work with hashes that have strings as keys, only symbols. EDIT: Just to be clear, tenderlove (Ruby/Rails committer) confirms that you do not need to edit the session to exploit this ( http://news.ycombinator.com/item?id=4999767 ). It's still unclear how it is possib…

Yes, exactly. This is only directly exploitable if the user can submit a hash with symbol keys. Otherwise, it seems like it would take some unusual code path in the app to exploit the vulnerability.

The original post of the problem goes like this:

1. Gain an application's secret key, used to sign session cookies. 2. Inject a marshalled hash with _symbol_ keys into the session cookie, sign it with the secret key. 3. Now you can exploit the SQL vulnerability in the dynamic finders, assuming the session value is used directly as input.

Re: SQL Injection Vulnerability in Ruby on Rails; affects all versions

#69
post #23

Earlier quoted context omitted.

tenderlove mentions it has been assigned CVE-2012-5664. This is that CVE: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-5664 It references two articles that require session secrets.

Yes, the article does mention session secrets. However, this exploit does not require session secrets. The person who wrote the blog post wrote about essentially two vulnerabilities: session forging and SQL injection.

I'm pretty sure that the injection only works when you can forge a session because sessions may contain marshalled symbols, and the dynamic finders only accepted symbol option keys as valid. You can't get Rails to construct symbols out of a params hash. Is this a separate vulnerability?

Re: SQL Injection Vulnerability in Ruby on Rails; affects all versions

#70

Earlier quoted context omitted.

You are going to have problems with this whenever you are composing SQL statement with any type of user-provided data as part of the raw SQL string passed to the server. This generally happens in one of two says: 1) (most common) You have a SQL statement that takes a user-provided parameter and you compose your SQL statement as a string, including that parameter (eg., sql = "SELECT * FROM person where id = " + form.i…

This is not the problem. Please stop spreading misinformation. ActiveRecord does escape user input. The exploit here is that under certain obscure circumstances it is possible trick ActiveRecord into thinking the user input is an options hash passed by the caller. From my understanding this is non-trivial to exploit on most applications, and requires passing in a Hash with symbol keys. This is still a vulnerability t…

Umm.. I didn't say that ActiveRecord doesn't escape user input. So, stop spreading misinformation about my post ;-)

The fact of the matter is, whether its in some dark edge-case or not, user-provided data is being used to compose a SQL statement that is being passed to the server. Escaped or otherwise, that's a recipe for an injection attack.

Post reply on HN