diff options
author | Ryuta Kamizono <kamipo@gmail.com> | 2019-04-20 21:13:31 +0900 |
---|---|---|
committer | Ryuta Kamizono <kamipo@gmail.com> | 2019-06-06 03:57:24 +0900 |
commit | 7696f44f6ff4d3eda8510b67eaab0441153430c3 (patch) | |
tree | 040ac9388a14c3d6709c7527b42cd760282958ff /activerecord/lib/active_record/sanitization.rb | |
parent | f166a01b4bfca7d32428095670a271d0771db797 (diff) | |
download | rails-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.rb | 33 |
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) |