File tree Expand file tree Collapse file tree 2 files changed +35
-2
lines changed
Expand file tree Collapse file tree 2 files changed +35
-2
lines changed Original file line number Diff line number Diff line change 11module MySQLBinUUID
2- class Type < ActiveModel :: Type :: Binary
2+ class InvalidUUID < StandardError ; end
33
4+ class Type < ActiveModel ::Type ::Binary
45 def type
56 :uuid
67 end
@@ -27,7 +28,16 @@ def cast(value)
2728 # it to the database.
2829 def serialize ( value )
2930 return if value . nil?
30- Data . new ( strip_dashes ( value ) )
31+ undashed_uuid = strip_dashes ( value )
32+
33+ # To avoid SQL injection, verify that it looks like a UUID. ActiveRecord
34+ # does not explicity escape the Binary data type. escaping is implicit as
35+ # the Binary data type always converts its value to a hex string.
36+ unless valid_undashed_uuid? ( undashed_uuid )
37+ raise MySQLBinUUID ::InvalidUUID , "#{ value } is not a valid UUID"
38+ end
39+
40+ Data . new ( undashed_uuid )
3141 end
3242
3343 # We're inheriting from the Binary type since ActiveRecord in that case
@@ -73,5 +83,10 @@ def strip_dashes(uuid)
7383 uuid . delete ( "-" )
7484 end
7585
86+ # Verify that the undashed version of a UUID only contains characters that
87+ # represent a hexadecimal value.
88+ def valid_undashed_uuid? ( value )
89+ value =~ /\A [[:xdigit:]]{32}\z /
90+ end
7691 end
7792end
Original file line number Diff line number Diff line change @@ -112,6 +112,24 @@ class MyUuidModelWithValidations < MyUuidModel
112112 assert_equal results . first , @my_model
113113 assert_equal results . first . the_uuid , sample_uuid
114114 end
115+
116+ it "can't be used to inject SQL using .where" do
117+ assert_raises MySQLBinUUID ::InvalidUUID do
118+ MyUuidModel . where ( the_uuid : "' OR ''='" ) . first
119+ end
120+ end
121+
122+ it "can't be used to inject SQL using .find_by" do
123+ assert_raises MySQLBinUUID ::InvalidUUID do
124+ MyUuidModel . find_by ( the_uuid : "' OR ''='" )
125+ end
126+ end
127+
128+ it "can't be used to inject SQL while creating" do
129+ assert_raises MySQLBinUUID ::InvalidUUID do
130+ MyUuidModel . create! ( the_uuid : "40' + x'40" )
131+ end
132+ end
115133 end
116134
117135end
You can’t perform that action at this time.
0 commit comments