6 ms·
SQL Injection Vulnerability in Rails
- danso 14y agoIs there an example of what this special hash looks like? E resulting hash that is, not necessarily the attack that leads to its construction.
- amalag 14y agoSeems they would be close enough that they didn't want to share it. Trying to avoid too many script kiddie attacks on unpatched rails servers.
- sanxiyn 14y agoYes. If you look at attached patches, they include this special hash in the test case.
- danso 14y agoAh thanks. Sorry, am reading from an iOS device and reflexively ignore all Download links at first.
- benmmurphy 14y agohttp://blog.pentesterlab.com/2012/06/cve-2012-2661-exploitation-write-up.html http://blog.pentesterlab.com/2012/06/cve-2012-2661-exploitat... since it is already public i'm thinking of adding my own write up
- speleding 14y agoI don't believe in security through obscurity but I really think the author of that blog post is not doing the world a favor by explaining how to use this bug with URI encoded copy/paste examples for every script kiddie to use, less than 24 hours after it hit. Anyway, the gist is: if you have an unpatched rails server stop reading this, you need to upgrade RIGHT AWAY.
- daeken 14y agoAnything that makes people more aware of security issues, what's involved in exploiting vulnerabilities, and how the other side things about these things, is a very good thing. The vast majority of programmers don't know a thing about security. Anything that can be done to improve that, even in the slightest, is a great thing for this world.
- Morg 14y agoExactly. OSX had very bad security before the first big news on virus's, and it won't have good security before another thousand big news on virus's, trojans and backdoors.
- speleding 14y agoLike I said, I'm not in favor of keeping it a secret, and I am all for making people aware, but "making people aware" does not have to be giving copy/paste examples to script kiddies of how to do the exploit within 24 hours of it being reported.
- cleaver 14y agoThe full disclosure debate is almost as old as the Internet itself. There's a case to be made on either side. Disclosers gonna disclose. Know what I'm saying?
- snyff 14y agoTo be honest, I think there is a lot more work to do (at least 2 more hours just to dump the database version) even for the author. I don't think any script kiddie will be able to exploit it based on the information provided. Or a least until someone put together a SQLmap tutorial for it. The URI here was just for people to test if they were vulnerable or not.
- tptacek 14y agoHow'd you find this? It's a good one.
- mikexstudios 14y agohttps://rubyonrails-security.googlegroups.com/attach/fc2da6c627fc92df/3-0-params_sql_injection.patch?view=1&part=3 https://rubyonrails-security.googlegroups.com/attach/fc2da6c... Scroll down to test_where_error.
- purephase 14y agoGood to know. Thanks for sharing.
- julian37 14y agoMakes me consider to start always casting URL query parameters as a defensive measure, regardless of this specific vulnerability being patched.
- michiel3 14y agoThis is probably a best practice you could learn yourself to implement every time you know for sure you don't want a GET/POST variable to be a hash/array. This can also prevent other application errors when someone passes a hash/array which is used somewhere in the code where it is expected to be a string or something.
- mseebach 14y agoI'm not terribly familiar with the Rails feature in question, but it seems to me that GET/POST params should never be interpreted automatically. Parsing a param into any other type than a string should be explicit.
- tptacek 14y agoYou're (respectfully) not terribly familiar with Rails, then, because the interpretation of foo[bar]=xxx as { :foo => { :bar => 'xxx' } } is one of the core patterns in the framework. Code all across the platform depends on that behavior.
- mseebach 14y agoI get it now. I though there was interpretation of the right hand side of the =.
- sim0n 14y agoThis is the same with PHP. Be aware anyone using something like MongoDB, if you don't sanitize/cast your inputs, your app could be vulnerable. e.g. if you have the code: $collection->findOne( array( 'username' => $_POST['username'], 'password' => $_POST['password'] ) ); someone could POST something like username[$ne]='?'&password[$ne]='?' and login.
- sparknlaunch 14y agoIn laymen terms what does this mean? I understood SQL injections are one of the most common forms of attack, therefore why has this happened on such a popular framework? Is it user error or rails error?
- danso 14y agoAppears to be Rails error. ActiveRecord provides a convenient method for accessing the database layer. Part of the convenience is that thhe method handles the sanitizing part...something which, when people have to write out themselves, tend to slip up on a rare (but too often) occasion. The bug reportedly occurs by sending this method a specifically crafted input, which bypasses the sanitization that prevents injection. So devs who have placed their trust in the ActiveRecord method now have compromised systems
- Morg 14y agoAs usual, when you trust a piece of code without reading the source, the fail will be strong. This is like java's GUID that are random but not unique, etc. you can't guess it from the function name or description, you need to know the internal process to know how it's going to explode and when.
- Cloven 14y ago95% of even good developers wouldn't be able to tell when a sql sanitization function is poorly coded or has a hidden gotcha. Having the source is not nearly as important as trusting the upstream to be smart and to promptly resolve security issues when discovered.
- Morg 14y agoI trust noone. except maybe the pgsql guys. However, imho on the topic of SQL injection, either escaping the escape characters is enough or you should change DBMSs / APIs right away. But really, security without reading sources is blind more or less calculated risk, not security.
- sce 14y agoThis only applies to ActiveRecord, I wonder if e.g. DataMapper is vulnerable in a similar way.
- snyff 14y agoSo far, I don't think DataMapper is vulnerable. The mapping is not done in the same way (datamapper use hard coded properties). As an example, the following User.all(':email '=> {':id' => '1"'}) will throw ArgumentError: condition ":email " does not map to a property or relationship in User because of the space before any SQL request is performed. and User.all(':email '=> {':id' => '1"'}) will create the following query: Query SELECT `id`, `email`, `password` FROM `users` WHERE `email` IN ('[":id", "1\""]') ORDER BY `id` 120602 8:41:03 3 Quit
- fendale 14y agoSigh - why oh why doesn't Rails use bind variables? Just about every DBMS I have used supports them (Sqlite, Mysql, Oracle, Sybase I know for sure) and if you correctly bind the variables into the query, fears about SQL Injection pretty much disappear. Then there is performance - in Oracle bind variables are essential for scalability. I read somewhere that Mysql performs better without bind variables. For most databases by caching prepared statement handles and binding / executing that handle many times, it will perform better than handling many one off queries. I have benchmarked a 20% improvement in throughput on Oracle by making just that change (which is a one liner in the JDBC driver).
- judofyr 14y agoThis has nothing to do with bind variables. It was not a bug in how variables were bound/escaped. The bug was that Rails treated a variable (which sometimes is a user input) as a column name in certain cases.
- fendale 14y agoI admit I had not read the actual bug report before I commented, but I just did and it reads: >Impacted code directly passes request params to the `where` method of an ActiveRecord class like this: Post.where(:id => params[:id]).all >An attacker can make a request that causes `params[:id]` to return a specially crafted hash that will cause the WHERE clause of the SQL statement to query an arbitrary table with some value. For me that is a classic SQL injection attack that can be avoided 100% of the time if you use bind variables for all user input into an SQL query. Rails doesn't use bind variables - it uses something that looks similar, but it is actually rails code that escapes and concatenates the user input into the query string before executing it. This bug was in that escaping code. However, if Rails correctly bound the inputs to all queries (which is pretty easy to do) then this escaping code could be removed totally and this problem would never have appeared.
- Morg 14y agoWell maybe you should check that again. Your approach sounds like you should have stored procs instead. Using prepared statements or variable binding to fight SQL injections is not the best idea, although its widespread. In most cases where you want a prepared statement, you'd be better off using a stored proc, as you'll skip the expensive optimization every single time. MySQL is not even a real RDBMS (no ACID, no triggers, fail APIs, etc.), anyone using it should switch to PostgreSQL yesterday unless their data really doesn't matter. SQL injections are 100% avoided by user input control in the application, and the simplest way is to escape all escape characters, that may require reading a bit of doc but w/e.
- deleted 14y ago[deleted]
- rabidsnail 14y agoI'm surprised more type system nazis haven't come out of the woodwork. This is one of the few serious production bugs that actually would have been caught by static typing.
- papsosouid 14y ago>few Well, at least you're funny.
- drivebyacct2 14y agoI liked the part where you insult and slander those of us that appreciate typing and also call out (just one of many) reasons why can be a "good thing".
- lsb 14y ago> type system nazis As a general rule of thumb, unless you mean to say that Hindley-Milner causes genocide, say "sticklers", or "evangelists", or "fanbois" even.
- deleted 14y ago[deleted]
- klodolph 14y agoHow do I read this? I just get a "sign in" wall... like all other "Google Groups" posts.
- Daniel_Newby 14y agoIIRC Google gets confused if you were once logged in. Either log in or delete your Google cookies.
- LogicX 14y agoAnyone using Nginx naxsi module to protect against this? https://code.google.com/p/naxsi/ https://code.google.com/p/naxsi/
- sams99 14y agoprepared statements often eliminate this vector ... the thing is, mysql2 the most popular db access gem for rails does not even implement prepared statements, and AR does not have a mechanism to send these to a db. In an ideal world the app passes the db gem 'select * from posts where Id = ?', [1] and then the gem takes care of preparing and executing. In all the real world web apps I have seen the number of "distinct" SQL statements they need to run are quite low (in the 100s) so preparing is a no brainer. I do not see this at all as a Ruby problem it has nothing to do with dynamic typing, I see it as a problem approach to db access. I believe Sequel (another less popular db gem for Ruby) is not even theoretically prone to these kind of issues.