Skip to content

Commit

Permalink
Document MySQL numeric quoting behavior in ActiveRecord::Sanitization
Browse files Browse the repository at this point in the history
Ref: #44312
Ref: #42440
Fix: #46776
  • Loading branch information
byroot committed Dec 22, 2022
1 parent 827ae3c commit 50d59e9
Showing 1 changed file with 24 additions and 0 deletions.
24 changes: 24 additions & 0 deletions activerecord/lib/active_record/sanitization.rb
Expand Up @@ -19,6 +19,14 @@ module ClassMethods
#
# sanitize_sql_for_conditions("name='foo''bar' and group_id='4'")
# # => "name='foo''bar' and group_id='4'"
#
# Note that this sanitization method is not schema-aware, hence won't do any type casting
# and will directly use the database adapter's +quote+ method.
# For MySQL specifically this means that numeric parameters will be quoted as strings
# to prevent query manimupation attacks.
#
# sanitize_sql_for_conditions(["role = ?", 0])
# # => "role = '0'"
def sanitize_sql_for_conditions(condition)
return nil if condition.blank?

Expand All @@ -43,6 +51,14 @@ def sanitize_sql_for_conditions(condition)
#
# sanitize_sql_for_assignment("name=NULL and group_id='4'")
# # => "name=NULL and group_id='4'"
#
# Note that this sanitization method is not schema-aware, hence won't do any type casting
# and will directly use the database adapter's +quote+ method.
# For MySQL specifically this means that numeric parameters will be quoted as strings
# to prevent query manimupation attacks.
#
# sanitize_sql_for_assignment(["role = ?", 0])
# # => "role = '0'"
def sanitize_sql_for_assignment(assignments, default_table_name = table_name)
case assignments
when Array; sanitize_sql_array(assignments)
Expand Down Expand Up @@ -125,6 +141,14 @@ def sanitize_sql_like(string, escape_character = "\\")
#
# sanitize_sql_array(["name='%s' and group_id='%s'", "foo'bar", 4])
# # => "name='foo''bar' and group_id='4'"
#
# Note that this sanitization method is not schema-aware, hence won't do any type casting
# and will directly use the database adapter's +quote+ method.
# For MySQL specifically this means that numeric parameters will be quoted as strings
# to prevent query manimupation attacks.
#
# sanitize_sql_array(["role = ?", 0])
# # => "role = '0'"
def sanitize_sql_array(ary)
statement, *values = ary
if values.first.is_a?(Hash) && /:\w+/.match?(statement)
Expand Down

0 comments on commit 50d59e9

Please sign in to comment.