Tuesday, March 19, 2013

Common Ruby/Rails/Rack Vulnerability: params[:some_sym].to_sym

Symbols are great when they are well-defined, because you avoid String creation and don't tend to create as much GC churn. But, sometimes the tendency to use symbols for keys can be a bad thing.

Case in point is CVE-2013-1854, fixed in Rails 3.2.13, 3.1.12, and 2.3.18.

If you can't use one of those versions of Rails, at least use the workaround provided in that notice for ActiveRecord:

... change code that looks like this:

User.where(:name => params[:name])
to code like this:
User.where(:name => params[:name].to_s) 

But, it goes beyond that. This should serve as a warning to not ever convert significantly variable/unknown user-provided values to symbols, ever, if you want to avoid a similar vulnerability. When you create a symbol, it is going to stay around and not be garbage-collected, so allowing any thing the user wants to become a symbol is both a possible memory leak issue and a DoS vulnerability.

Change anything that would ever do the equivalent (directly or indirectly) of:

params[:some_sym].to_sym

to leave the value as a String:

params[:some_sym]

and do whatever else you need to do to ensure that user-defined values in part or whole don't become lots and lots of symbols.

Also, even though it may introduce a little extra churn, if for whatever reason you aren't sure that the value in params is a String, then use to_s, to_i, ... (any of the usual numeric conversions) on it, to attempt to enforce type.

No comments: