rubygem-activerecord/CVE-2022-44566.patch
wszlight 87c00726ad fix CVE-2022-44566
fix CVE-2022-44566 CVE-2023-22794

(cherry picked from commit ead83c6d23c77103756b10a0ec6501a8a5601c52)
2023-02-23 17:19:28 +08:00

133 lines
5.3 KiB
Diff

From 4f44aa9d514e701ada92b5cf08beccf566eeaebf Mon Sep 17 00:00:00 2001
From: Zack Deveau <zack.ref@gmail.com>
Date: Tue, 22 Nov 2022 09:48:59 -0500
Subject: [PATCH] Added integer width check to PostgreSQL::Quoting
Given a value outside the range for a 64bit signed integer type
PostgreSQL will treat the column type as numeric. Comparing
integer values against numeric values can result in a slow
sequential scan.
This behavior is configurable via
ActiveRecord::Base.raise_int_wider_than_64bit which defaults to true.
[CVE-2022-44566]
---
.../connection_adapters/postgresql/quoting.rb | 26 +++++++++++++++++
activerecord/lib/active_record/core.rb | 7 +++++
.../cases/adapters/postgresql/quoting_test.rb | 28 +++++++++++++++++++
3 files changed, 78 insertions(+)
diff --git a/activerecord-6.1.4.1/lib/active_record/connection_adapters/postgresql/quoting.rb b/activerecord-6.1.4.1/lib/active_record/connection_adapters/postgresql/quoting.rb
index 3d94d4bb36..4db5f8f528 100644
--- a/activerecord-6.1.4.1/lib/active_record/connection_adapters/postgresql/quoting.rb
+++ b/activerecord-6.1.4.1/lib/active_record/connection_adapters/postgresql/quoting.rb
@@ -4,6 +4,12 @@
module ConnectionAdapters
module PostgreSQL
module Quoting
+ class IntegerOutOf64BitRange < StandardError
+ def initialize(msg)
+ super(msg)
+ end
+ end
+
# Escapes binary strings for bytea input to the database.
def escape_bytea(value)
@connection.escape_bytea(value) if value
@@ -120,7 +126,27 @@ def lookup_cast_type(sql_type)
super(query_value("SELECT #{quote(sql_type)}::regtype::oid", "SCHEMA").to_i)
end
+ def check_int_in_range(value)
+ if value.to_int > 9223372036854775807 || value.to_int < -9223372036854775808
+ exception = <<~ERROR
+ Provided value outside of the range of a signed 64bit integer.
+
+ PostgreSQL will treat the column type in question as a numeric.
+ This may result in a slow sequential scan due to a comparison
+ being performed between an integer or bigint value and a numeric value.
+
+ To allow for this potentially unwanted behavior, set
+ ActiveRecord::Base.raise_int_wider_than_64bit to false.
+ ERROR
+ raise IntegerOutOf64BitRange.new exception
+ end
+ end
+
def _quote(value)
+ if ActiveRecord::Base.raise_int_wider_than_64bit && value.is_a?(Integer)
+ check_int_in_range(value)
+ end
+
case value
when OID::Xml::Data
"xml '#{quote_string(value.to_s)}'"
diff --git a/activerecord-6.1.4.1/lib/active_record/core.rb b/activerecord-6.1.4.1/lib/active_record/core.rb
index 9f1584d46b..d3bfd4929e 100644
--- a/activerecord-6.1.4.1/lib/active_record/core.rb
+++ b/activerecord-6.1.4.1/lib/active_record/core.rb
@@ -163,6 +163,13 @@ def self.configurations
# to Psych safe_load in the YAML Coder
mattr_accessor :yaml_column_permitted_classes, instance_writer: false, default: [Symbol]
+ ##
+ # :singleton-method:
+ # Application configurable boolean that denotes whether or not to raise
+ # an exception when the PostgreSQLAdapter is provided with an integer that is
+ # wider than signed 64bit representation
+ mattr_accessor :raise_int_wider_than_64bit, instance_writer: false, default: true
+
self.filter_attributes = []
def self.connection_handler
diff --git a/test/cases/adapters/postgresql/quoting_test.rb b/test/cases/adapters/postgresql/quoting_test.rb
index d571355a9c..125565f9c8 100644
--- a/test/cases/adapters/postgresql/quoting_test.rb
+++ b/test/cases/adapters/postgresql/quoting_test.rb
@@ -8,6 +8,7 @@
class QuotingTest < ActiveRecord::PostgreSQLTestCase
def setup
@conn = ActiveRecord::Base.connection
+ @raise_int_wider_than_64bit = ActiveRecord::Base.raise_int_wider_than_64bit
end
def test_type_cast_true
@@ -44,6 +45,33 @@ def test_quote_table_name_with_spaces
value = "user posts"
assert_equal "\"user posts\"", @conn.quote_table_name(value)
end
+
+ def test_raise_when_int_is_wider_than_64bit
+ value = 9223372036854775807 + 1
+ assert_raise ActiveRecord::ConnectionAdapters::PostgreSQL::Quoting::IntegerOutOf64BitRange do
+ @conn.quote(value)
+ end
+
+ value = -9223372036854775808 - 1
+ assert_raise ActiveRecord::ConnectionAdapters::PostgreSQL::Quoting::IntegerOutOf64BitRange do
+ @conn.quote(value)
+ end
+ end
+
+ def test_do_not_raise_when_int_is_not_wider_than_64bit
+ value = 9223372036854775807
+ assert_equal "9223372036854775807", @conn.quote(value)
+
+ value = -9223372036854775808
+ assert_equal "-9223372036854775808", @conn.quote(value)
+ end
+
+ def test_do_not_raise_when_raise_int_wider_than_64bit_is_false
+ ActiveRecord::Base.raise_int_wider_than_64bit = false
+ value = 9223372036854775807 + 1
+ assert_equal "9223372036854775808", @conn.quote(value)
+ ActiveRecord::Base.raise_int_wider_than_64bit = @raise_int_wider_than_64bit
+ end
end
end
end
--
2.35.1