This thread references:
http://www.ruby-forum.com/topic/90258#new
http://www.ruby-forum.com/topic/82349#143790
ActiveRecord’s find() method has built in ways to avoid SQL injection by
using the format
:conditions => [ “user_name = ?”, user_name]
Is there any such system for escaping injection in :order? It seems to
only take a string and feed it to the SQL statement. This causes a
vulnerability when using params to set :order as in this function:
def list
sort_by = params[:sort_by]
@book_pages, @books = paginate :books,
:order => sort_by,
:per_page => 10
end
We’ve tried a few methods to sanitize sort_by such as :order => [‘?’,
sort_by] but it just passes that to the SQL statement like a flattened
array. The ‘escaping magic’ does not work for :order. Should I use
gsub! to sanitize params[:sort_by]?
Taylor S. wrote:
Is there any such system for escaping injection in :order?
Maybe check it first to make sure it’s actually one of the columns in
the model?
sort_by = params[:sort_by] if
Book.column_names.include?(params[:sort_by])
How about calling ActiveRecord#sanitize_sql directly?
Danny B. wrote:
How about calling ActiveRecord#sanitize_sql directly?
–
Posted via http://www.ruby-forum.com/.
My solution to this is to have the params[:sort] point to a key for a
hash of predefined sort options.
sort_options = { ‘name_up’ => ‘name ASC, created_at DESC’,
‘name_down’=>‘name DESC, created_at DESC’}
then use
Object.find(:all, :order=>sort_options[params[:sort]])
If the :sort parameter is messed up, it will return the Hash.default.
_Kevin
Chris: your way works well and is pretty low maintenance. Tested and
works by simply discarding any sort_bys without matching columns.
Thanks!
Danny: The API docs on ActiveRecord#sanitize_sql are terrible, even by
Rails standards! I’m not sure how to do it.
Kevin: Your way would definitely work, but it would be a lot of
maintenance as models and attributes change.
I was ultimately hoping for some way to sanitize sort_by so that I could
use it as an application helper for all the times I want to sort. The
search continues! Thanks everyone for your help.
Here is the epilogue - I created this module (comments removed):
def set_sort_method(model)
unless params[:sort_by].nil?
if model.column_names.include?(params[:sort_by])
@sort_by = params[:sort_by]
end
unless session[:sort_by].nil?
if session[:sort_by] == @sort_by
@sort_by += ’ desc’
end
end
session[:sort_by] = @sort_by
end
end
And then all I have to add in the controller is set_sort_method() and
:order => @sort_by:
def list
set_sort_method(Publisher)
@publisher_pages, @publishers = paginate :publishers,
:order => @sort_by,
:per_page => 10
end
This works for every model and is DRY. Thanks again!
On 5 December 2006 01:33, Taylor S. wrote:
Chris: your way works well and is pretty low maintenance. Tested and
works by simply discarding any sort_bys without matching columns.
Thanks!
Danny: The API docs on ActiveRecord#sanitize_sql are terrible, even by
Rails standards! I’m not sure how to do it.
Kevin: Your way would definitely work, but it would be a lot of
maintenance as models and attributes change.
Personally, I would stick with Kevin’s suggestion on “sorting names” and
here
is why:
- Chris’ solution doesn’t allow to handle multiple sort params (e.g.
‘company
desc, name asc’)
- Kevin’s solution IMHO is more flexible and secure.
- Danny, probably, right but it’s not straight forward.
end
end
session[:sort_by] = @sort_by
You might want to do…
session[:sort_by][model]…
here and a couple of lines up to avoid any conflicts arrising from
multiple browser windows open to different pages, etc…
Maxim K. wrote:
Personally, I would stick with Kevin’s suggestion on “sorting names” and
here is why:
- Chris’ solution doesn’t allow to handle multiple sort params (e.g.
‘company
desc, name asc’)
- Kevin’s solution IMHO is more flexible and secure.
What would be the best way to implement this? Give each model a class
method (called “sort_hash” or something) that returns the hash Kevin
describes?
On 5 December 2006 17:19, Chris G. wrote:
method (called “sort_hash” or something) that returns the hash Kevin
describes?
Personally, I had this “hash” in my controller which should show my
corresponding model data.
You see, it’s not a generic way to order collections (you have :order
param
already). It’s, IMHO, handy way to make sure that no sql injection will
occur.
Chris G. wrote:
method (called “sort_hash” or something) that returns the hash Kevin
describes?
–
Posted via http://www.ruby-forum.com/.
You could do that. I tend to customize the hash for each particular
view (or I only ever use it in one), so I just define it right in the
view action. In my view, this is part of the ‘view’ part of MVC, so
the model should probably not be aware of it.
_Kevin