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 
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
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