Unsafe Query Generation Risk in Active Record

Metadata

medium
5.0
activerecord
CVE-2016-6317
groups.google.com
2016-08-11
2017-06-16 19:20
CVE-2016-6317 rails
CVE-2016-6317
2017-04-01 19:10
2017-02-22 23:03
2017-01-05 20:15

Description

There is a vulnerability when Active Record is used in conjunction with JSON
parameter parsing. This vulnerability is similar to CVE-2012-2660,
CVE-2012-2694 and CVE-2013-0155.

Impact
------

Due to the way Active Record interprets parameters in combination with the way
that JSON parameters are parsed, it is possible for an attacker to issue
unexpected database queries with "IS NULL" or empty where clauses. This issue
does *not* let an attacker insert arbitrary values into an SQL query, however
they can cause the query to check for NULL or eliminate a WHERE clause when
most users wouldn't expect it.

For example, a system has password reset with token functionality:

```ruby
unless params[:token].nil?
user = User.find_by_token(params[:token])
user.reset_password!
end
```

An attacker can craft a request such that `params[:token]` will return
`[nil]`. The `[nil]` value will bypass the test for nil, but will still add
an "IN ('xyz', NULL)" clause to the SQL query.

Similarly, an attacker can craft a request such that `params[:token]` will
return an empty hash. An empty hash will eliminate the WHERE clause of the
query, but can bypass the `nil?` check.

Note that this impacts not only dynamic finders (`find_by_*`) but also
relations (`User.where(:name => params[:name])`).

All users running an affected release should either upgrade or use one of the
work arounds immediately. All users running an affected release should upgrade
immediately. Please note, this vulnerability is a variant of CVE-2012-2660,
CVE-2012-2694, and CVE-2013-0155. Even if you upgraded to address those
issues, you must take action again.

If this chance in behavior impacts your application, you can manually decode
the original values from the request like so:

`ActiveSupport::JSON.decode(request.body)`

Workarounds
-----------
This problem can be mitigated by casting the parameter to a string before
passing it to Active Record. For example:

```ruby
unless params[:token].nil? || params[:token].to_s.empty?
user = User.find_by_token(params[:token].to_s)
user.reset_password!
end
```

Am I vulnerable?

The constraints below list the versions that this vulnerability is patched in, and versions that are unaffected. If a patch is ready but unrealeased, then it is pending.

Or, you can just let us figure it out for you! Appcanary continously monitor your installed packages, and tell you if any of them are vulnerable.

Sign up for monitoring

Affected package information

Package Patched in Unaffected in
activerecord >= 4.2.7.1 < 4.2.0,>= 5.0.0