aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/sanitization.rb
diff options
context:
space:
mode:
authorRyuta Kamizono <kamipo@gmail.com>2019-04-20 21:13:31 +0900
committerRyuta Kamizono <kamipo@gmail.com>2019-06-06 03:57:24 +0900
commit7696f44f6ff4d3eda8510b67eaab0441153430c3 (patch)
tree040ac9388a14c3d6709c7527b42cd760282958ff /activerecord/lib/active_record/sanitization.rb
parentf166a01b4bfca7d32428095670a271d0771db797 (diff)
downloadrails-7696f44f6ff4d3eda8510b67eaab0441153430c3.tar.gz
rails-7696f44f6ff4d3eda8510b67eaab0441153430c3.tar.bz2
rails-7696f44f6ff4d3eda8510b67eaab0441153430c3.zip
Allow quoted identifier string as safe SQL string
Currently `posts.title` is regarded as a safe SQL string, but `"posts"."title"` (it is a result of `quote_table_name("posts.title")`) is regarded as an unsafe SQL string even though a result of `quote_table_name` should obviously be regarded as a safe SQL string, since the column name matcher doesn't respect quotation, it is a little annoying. This changes the column name matcher to allow quoted identifiers as safe SQL string, now all results of the `quote_table_name` are regarded as safe SQL string.
Diffstat (limited to 'activerecord/lib/active_record/sanitization.rb')
-rw-r--r--activerecord/lib/active_record/sanitization.rb33
1 files changed, 31 insertions, 2 deletions
diff --git a/activerecord/lib/active_record/sanitization.rb b/activerecord/lib/active_record/sanitization.rb
index 750766714d..5296499bad 100644
--- a/activerecord/lib/active_record/sanitization.rb
+++ b/activerecord/lib/active_record/sanitization.rb
@@ -61,8 +61,9 @@ module ActiveRecord
# # => "id ASC"
def sanitize_sql_for_order(condition)
if condition.is_a?(Array) && condition.first.to_s.include?("?")
- disallow_raw_sql!([condition.first],
- permit: AttributeMethods::ClassMethods::COLUMN_NAME_WITH_ORDER
+ disallow_raw_sql!(
+ [condition.first],
+ permit: connection.column_name_with_order_matcher
)
# Ensure we aren't dealing with a subclass of String that might
@@ -133,6 +134,34 @@ module ActiveRecord
end
end
+ def disallow_raw_sql!(args, permit: connection.column_name_matcher) # :nodoc:
+ unexpected = nil
+ args.each do |arg|
+ next if arg.is_a?(Symbol) || Arel.arel_node?(arg) ||
+ arg.to_s.split(/\s*,\s*/).all? { |part| permit.match?(part) }
+ (unexpected ||= []) << arg
+ end
+
+ return unless unexpected
+
+ if allow_unsafe_raw_sql == :deprecated
+ ActiveSupport::Deprecation.warn(
+ "Dangerous query method (method whose arguments are used as raw " \
+ "SQL) called with non-attribute argument(s): " \
+ "#{unexpected.map(&:inspect).join(", ")}. 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()."
+ )
+ else
+ raise(ActiveRecord::UnknownAttributeReference,
+ "Query method called with non-attribute argument(s): " +
+ unexpected.map(&:inspect).join(", ")
+ )
+ end
+ end
+
private
def replace_bind_variables(statement, values)
raise_if_bind_arity_mismatch(statement, statement.count("?"), values.size)