New Rails SQL Injection Vulnerability Uncovered

A new SQL-injection vulnerability for the new year, this time in an otherwise common and innocuous-looking part of Ruby on Rails’ ActiveRecord:

Post.find_by_id(params[:id]) 

It is disappointing that the default ORM in Rails cannot yet safely query by identifier, a task made trivial by pre-compiled DBI queries using placeholders, or in this case, a single placeholder!

Check the original post for workaround.

About Joe Atzberger

Joe Atzberger (atz) is a library hacker in Palo Alto, CA. He worked with Galen at both LibLime and Equinox Software, Inc. as an open source developer on Koha and Evergreen. Joe currently works on Hydra and institutional digital repository infrastructure at Stanford.

4 Responses to New Rails SQL Injection Vulnerability Uncovered

  1. There’s a LOT of mis-information and snarky “why is Rails incompetent” posts about this vulnerability from people who don’t understand it or Rails, and I am going to say I think you’re adding to it.

    To try and keep from seeming a “rails fanboy”, I’m going to start by saying that one of the odd things about the hysteria over this vulnerability is that there have been WORSE Rails vulnerabilities — including SQL injection vulnerabilities — found in the past 8 months which have oddly _not_ received this level of attention!

    > It is disappointing that the default ORM in Rails cannot yet safely query by identifier,

    Sure it can. The _typical_ way to query by identifier is `Post.find(params[:id])` which is not subject to this vulnerability. (I can’t say if it’s subject to other as of yet unknown vulnerabilities!).

    This vulnerability affects ActiveRecord’s “dynamic finder” methods, find_by_x where x is an arbitrary attribute defined on your model. And find_by_id(params[:id]) would NOT ordinarily trigger it — to trigger it, you need to pass something as an argument which a) is a hash, and b) has a key which is a ruby symbol not a ruby string. While it’s possible for params[:id] in Rails to be a hash when you didn’t expect it to be because of an attackers action (thus triggering the vulnerability), it’s not ordinarily possible for it to be a hash containing a symbol (rather than string) key. The popular auth_logic gem exposed itself to this vulnerability (which is how it was discovered) by using cookie/session data in a find_by_x call, rather than get/post query params (which ordinarily would not trigger it).

    It was a vulnerability, it was patched. But to talk about how “disappointing” or “trivial” this vulnerability was, you need to actually understand what was going on, which most commentators contributing to the hysteria, including you, do not.

  2. I’d also add that at the same time this vulnerability was announced, patch releases to Rails 3.0.x, 3.1.x, and 3.2.x were also released. So there’s no need for a ‘workaround’, rather than simply updating your Rails version. And even IF this vulnerability prevented Rails from “safely querying by identifier” (it did not), it would not be accurate to say “Rails can not yet” do it, since security releases fixing this vulnerability have already been released, so it’s already ‘yet’.

  3. When I say “by identifier” here, I mean “by_id”, as the function in question. Sorry if that was unclear. I disagree that minor complexity of params is at all mitigating in the degree to which this vulnerability would be exploited. Nobody is handcrafting exploits anymore.

    And I don’t think this 6-line post is in any way a pile-on of criticism or “hysteria”. My source of information is the post itself and the patches themselves after discussing them with the developers I work with. You are correct that the patches are released to supported branches. This is good; it rectifies the problem. But to act like the vulnerability isn’t disappointing is ludicrous. I never described the vulnerability as trivial, I said avoiding SQL-injection w/ proper use of (in this case) a single placeholder IS. If you were writing an SQL query yourself here, you would have avoided this problem. Another way of saying that is that Rails’ encapsulation of complexity is not without risk.

    I don’t really care about the evenness of coverage in the coder community on past Rails vulnerabilities. If you want to write them up, please do. 8 months ago I was developing on a different stack, and now it’s a cluster of Rails apps. This affects our development directly, so I don’t need to claim special knowledge of Rails internals to find notification about this valuable enough to post.

  4. Related vulnerability with dynamic finders (query clause alteration, but not SQL injection):
    https://groups.google.com/forum/?fromgroups=#!topic/rubyonrails-security/t1WFuuQyavI