diff options
author | Matthew Draper <matthew@trebex.net> | 2017-11-14 23:27:50 +1030 |
---|---|---|
committer | Matthew Draper <matthew@trebex.net> | 2017-11-14 23:30:45 +1030 |
commit | a1ee43d2170dd6adf5a9f390df2b1dde45018a48 (patch) | |
tree | e1fd861d4e370e81c312aa1b4fde45eff48c08f1 /activerecord/lib/active_record/attribute_methods.rb | |
parent | ed100166874fb4a542c5aaba933a4cca5ed72269 (diff) | |
parent | 4a5b3ca972e867d9b9276dcd98b0a6b9b6fb7583 (diff) | |
download | rails-a1ee43d2170dd6adf5a9f390df2b1dde45018a48.tar.gz rails-a1ee43d2170dd6adf5a9f390df2b1dde45018a48.tar.bz2 rails-a1ee43d2170dd6adf5a9f390df2b1dde45018a48.zip |
Merge pull request #27947 from mastahyeti/unsafe_raw_sql
Disallow raw SQL in dangerous AR methods
Diffstat (limited to 'activerecord/lib/active_record/attribute_methods.rb')
-rw-r--r-- | activerecord/lib/active_record/attribute_methods.rb | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb index 23d2aef214..64f81ca582 100644 --- a/activerecord/lib/active_record/attribute_methods.rb +++ b/activerecord/lib/active_record/attribute_methods.rb @@ -167,6 +167,46 @@ module ActiveRecord end end + # Regexp whitelist. Matches the following: + # "#{table_name}.#{column_name}" + # "#{column_name}" + COLUMN_NAME_WHITELIST = /\A(?:\w+\.)?\w+\z/i + + # Regexp whitelist. Matches the following: + # "#{table_name}.#{column_name}" + # "#{table_name}.#{column_name} #{direction}" + # "#{column_name}" + # "#{column_name} #{direction}" + COLUMN_NAME_ORDER_WHITELIST = /\A(?:\w+\.)?\w+(?:\s+asc|\s+desc)?\z/i + + def enforce_raw_sql_whitelist(args, whitelist: COLUMN_NAME_WHITELIST) # :nodoc: + unexpected = args.reject do |arg| + arg.kind_of?(Arel::Node) || + arg.is_a?(Arel::Nodes::SqlLiteral) || + arg.is_a?(Arel::Attributes::Attribute) || + arg.to_s.split(/\s*,\s*/).all? { |part| whitelist.match?(part) } + end + + return if unexpected.none? + + 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.0. 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 + # Returns true if the given attribute exists, otherwise false. # # class Person < ActiveRecord::Base |