182
loading...
This website collects cookies to deliver better user experience
delete_all
and destroy_all
could be passed a string of raw SQL.delete_by
and destroy_by
accept the same type of arguments as where
: a Hash, an Array, or a raw SQL String.params[:id] = "1) OR 1=1--"
User.delete_by("id = #{params[:id]}")
DELETE FROM "users" WHERE (id = 1) OR 1=1--)
User.order("name #{params[:direction]}")
DEPRECATION WARNING: Dangerous query method (method whose arguments are used as raw SQL) called with non-attribute argument(s): "--". Non-attribute arguments will be disallowed in Rails 6.1. This method should not be called with user-provided values, such as request parameters or model attributes. Known-safe values can be passed by wrapping them in Arel.sql().
order
. If the arguments do not appear to be column names or sort order, they will be rejected:> User.order("name ARGLBARGHL")
Traceback (most recent call last):
1: from (irb):12
ActiveRecord::UnknownAttributeReference (Query method called with non-attribute argument(s): "name ARGLBARGHL")
params[:direction] = ", 8"
User.order("name #{params[:direction]}")
ActiveRecord::StatementInvalid (SQLite3::SQLException: 2nd ORDER BY term out of range - should be between 1 and 7)
pluck
(somewhat surprisingly!) accepted arbitrary SQL strings if they were given in an array.order
/reorder
, Rails 6.0 started warning about this:> User.pluck(["1"])
DEPRECATION WARNING: Dangerous query method (method whose arguments are used as raw SQL) called with non-attribute argument(s): ["1"]. Non-attribute arguments will be disallowed in Rails 6.1. This method should not be called with user-provided values, such as request parameters or model attributes. Known-safe values can be passed by wrapping them in Arel.sql().
pluck
now only accepts attribute names!reselect
, which allows one to completely replace the SELECT
clause of a query. Like select
, it accepts any SQL string. Since SELECT
is at the very beginning of the SQL query, it makes it a great target for SQL injection.params[:column] = "* FROM orders -- "
User.select(:name).reselect(params[:column])
SELECT * FROM orders -- FROM "users"
where
, it is very easy to open up rewhere
to SQL injection.params[:age] = "1=1) OR 1=1--"
User.where(name: "Bob").rewhere("age > #{params[:age]}")
SELECT "users".* FROM "users" WHERE "users"."name" = ? AND (age > 1=1) OR 1=1--)