Escapowanie opcji metody find

witam

chcę zrobić dynamiczne sortowanie wyszukiwanych rekordów (np z selecta na stronie)

tzn

Offer.find(:all, :order => params[:order])

jak najsprawniej zabezpieczyć się przed sql injection?

nie znalazłem metody do escapeowania sql a placeholdery sa dostęopne tylko dla warunków.

Dopóki używasz tej metody w taki sposób jak podałeś to metoda sama zadba o to. O eskejpowanie musiałbyś się martwić przy Offer.find(:all, :conditions => [“status = #{params[:status]}”]) ale już nie przy Offer.find(:all, :conditions => {:status => params[:status]}) czy też Offer.find(:all, :conditions => [“status = ?”, params[:status]]).

zgadza się przy :conditions jest escapowanie ale przy :order już nie ma

[code]sql_injection = “rób ze mną co chcesz ’ …”
@offers = Offer.find(:all, :conditions => [“name like ?”, sql_injection], :order => sql_injection )

SELECT * FROM offers WHERE (name like ‘rób ze mną co chcesz ’ …’) ORDER BY rób ze mną co chcesz ’ …[/code]
’ w order nie jest escapowany :frowning:

pytanie również czy można skutecznie atakować order by i czy standartowe escapowanie zapobiegnie takim atakom

offtopic - cos jest nie tak z godziną na forum

Faktycznie, masz rację. Spróbuj zatem coś takiego:

:order => Offer.connection.quote_column_name(params[:order])

Zobacz też inne metody quote_* http://apidock.com/rails/ActiveRecord/ConnectionAdapters/Quoting/quote

dzieki

Najlepiej zbudować tablicę dozwolonych wartości dla order i przepuszczać tylko te wartości które się w niej znajdują a nie bezpośrednio interpolować do zapytania tak jak powyżej, np:

[code=ruby]class Model
named_scope :ordered_by, lambda {|param|
order = case param
when ‘newest’
‘created_at DESC’
when ‘oldest’
‘created_at ASC’
when ‘most_popular’
‘viewed DESC’
when ‘status’
‘state’
when ‘title’
‘title’
end
{ :order => order }
}
end

Model.ordered_by(‘oldest’).all[/code]
Trzeba tylko pamiętać, że named scopes “nakładają” parametr :order jeden na drugi jeśli są wiązane w wywołaniu ( nie nadpisują go ), eg:

[code=ruby]class Model

named_scope :latest, :order => ‘created_at DESC’
end[/code]
Model.viewed.latest.all - wykona “ORDER BY viewed DESC, created_at DESC” a nie “ORDER BY created by DESC” jak mogłoby się wydawać

Znalazłem taki fajny plugin wspomagający sortowanie http://github.com/runcoderun/sortable_table/tree/master
moze sie komuś przyda