Skip to content

Commit 536503d

Browse files
tenderloverafaelfranca
authored andcommitted
Fix possible DoS vector in PostgreSQL money type
Carefully crafted input can cause a DoS via the regular expressions used for validating the money format in the PostgreSQL adapter. This patch fixes the regexp. Thanks to @dee-see from Hackerone for this patch! [CVE-2021-22880]
1 parent bf8c59c commit 536503d

2 files changed

Lines changed: 10 additions & 2 deletions

File tree

  • activerecord

activerecord/lib/active_record/connection_adapters/postgresql/oid/money.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ def cast_value(value)
2626

2727
value = value.sub(/^\((.+)\)$/, '-\1') # (4)
2828
case value
29-
when /^-?\D*[\d,]+\.\d{2}$/ # (1)
29+
when /^-?\D*+[\d,]+\.\d{2}$/ # (1)
3030
value.gsub!(/[^-\d.]/, "")
31-
when /^-?\D*[\d.]+,\d{2}$/ # (2)
31+
when /^-?\D*+[\d.]+,\d{2}$/ # (2)
3232
value.gsub!(/[^-\d,]/, "").sub!(/,/, ".")
3333
end
3434

activerecord/test/cases/adapters/postgresql/money_test.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,14 @@ def test_money_type_cast
6464
assert_equal(-2.25, type.cast(+"(2.25)"))
6565
end
6666

67+
def test_money_regex_backtracking
68+
type = PostgresqlMoney.type_for_attribute("wealth")
69+
Timeout.timeout(0.1) do
70+
assert_equal(0.0, type.cast("$" + "," * 100000 + ".11!"))
71+
assert_equal(0.0, type.cast("$" + "." * 100000 + ",11!"))
72+
end
73+
end
74+
6775
def test_sum_with_type_cast
6876
@connection.execute("INSERT INTO postgresql_moneys (id, wealth) VALUES (1, '123.45'::money)")
6977

0 commit comments

Comments
 (0)