The overreaction on this page is ridiculous. Has anyone actually read the steps required to exploit this vulnerability?
You do know that to be able to exploit it you have to know the application's secret key, so you can create your own malicious encrypted session cookie that includes hashes instead of strings for the auth token lookup?
You do know that if someone has your app's secret key they can just write whatever they want into the session cookie, instantly compromising a large number of apps anyway? That's the whole point of the secret key!
This is an obscure issue which can be used to get around one layer of defense in rails security. It could never get around all of them. It requires intimate in-depth knowledge of the app to even attempt the exploit. Sure, it's a bug, and it's not to be taken lightly, but the howls of derision here are totally out of proportion.
But that is an overreaction. The find_by_* dynamic handlers have always accepted strings and integers, by design. What's insecure about User.find_by_id("27")?
What people seem to be reacting to is the idea that User.find_by_id(params[:id]) is exploitable because you can coerce params[:id] into a hash instead of a string (by using a query string like ?id[select]=some_thing_here instead of ?id=27). True, but what most people here are overlooking is that User.find_by_id actually rejects these hashes because their keys are strings and not symbols. Try it out.
This vulnerability can be coupled with other vulnerabilities (like having someone's session secret, which is a much worse vulnerability IMO), but people are talking about it as if you can do something nasty with it by itself alone. That's why it's an overreaction.
Yes, this page has a real torches-and-pitchforks feel to it. It's quite absurd.
The howls of derision from people who flat out say they don't even use the framework and clearly don't understand the vulnerability are particularly ridiculous.
From looking at it, it seems that ANY HTTP parameter (e.g. POST or GET - which are completely user-controlled) can be manipulated if you know how it's going to be used in the code, e.g. an obvious object ID.
You need a way to inject symbols as hash keys. Normal parameter handling does not allow this, so you need a different way to exploit the bug. As venus says, session forging is one way. Regular parameter handling is not.
That's a bug/exploit in Authlogic, a third party library for rails, not rails.
However, that bug/exploit is based on the rails vuln and was patched in authlogic exactly how the Rails report instructed people to work around it (casting the parameter to a string).
Reading the actual report linked in the OP you'll see that generic and boilerplate code (e.g. the extremely common pattern: "Post.find_by_id(params[:id])") is going to be vulnerable to this bug.
"This leaves persist_by_session open to sql attacks (such as logging in as any user), if a malicious user can write their own rails session cookie (if they have the rails secret_token)."
The key is: "if they have the rails secret_token"
The secret token is autogenerated when the application is initially bootstrapped. Here is more information about it from any config/initializers/secret_token.rb file:
# Your secret key for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!
# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
Good catch, I'm glad that it's a best practice. I wasn't trying to shame those projects, I'm not a rubiest so I was just trying to figure out how someone might gain access to a secret token.
That's an interesting issue (Django has the same issue with its SECRET_KEY). If you have an open-source project that utilizes these kinds of technologies, you need to keep your secret key secret.
As it says in the Django settings:
"Make this unique, and don't share it with anybody."
Incidentally, this is one reason why the 12-factor app methodology stores configuration in environment variables, not source files. http://www.12factor.net/config
The linked pull request described a method for getting unescaped code into the application so the issue with find_by_id might be exploited.
Have you got another way of getting unescaped code into the application such that this issue might be exploited? If so, the core team will be very, very interested to hear from you.
I've been going through the code for ActiveRecord and now AuthLogic. I'm admittedly not well versed in Ruby.
However from the description of the vulnerability found at [1], it would appear as though the cookie value can be set to a Ruby string value that is then parsed by server to produce a Ruby Hash value (rather than the AuthLogic plugin's assumed string value).
Is the eval() of the cookie value done by Rails or is it done by AuthLogic? Is that a potential security vulnerability in itself?
params[:id] = {:select => "select * from users where admin = 1 limit 1; --"}
User.find_by_id(params[:id]) # => finds the first admin
# generated SQL:
# SELECT * from users where admin = 1 limit 1; -- select * FROM `users` WHERE (`users`.`id` IS NULL) LIMIT 1
Seems like a bigger bug than you seem to think it is. Merely accepting JSON and not calling .to_i is enough for me to select any user.
-- edit: maybe nvm on that, it requires an actual symbol, not a string key with a hash with indifferent access, like you'd get from JSON. Unless someone knows a way to get a symbol into a JSON or form-encoded field? Though you're vulnerable to this specifically if you use '.symbolize_keys' anywhere before it's passed in.
-- edit2: and I see I'm late to the game anyway, thanks tenderlove :)
You do know that to be able to exploit it you have to know the application's secret key, so you can create your own malicious encrypted session cookie that includes hashes instead of strings for the auth token lookup?
You do know that if someone has your app's secret key they can just write whatever they want into the session cookie, instantly compromising a large number of apps anyway? That's the whole point of the secret key!
This is an obscure issue which can be used to get around one layer of defense in rails security. It could never get around all of them. It requires intimate in-depth knowledge of the app to even attempt the exploit. Sure, it's a bug, and it's not to be taken lightly, but the howls of derision here are totally out of proportion.