Skip to content

Commit 7042887

Browse files
committed
Remove '\u0000' from input when sanitizing null input
1 parent f2bcf86 commit 7042887

File tree

2 files changed

+17
-3
lines changed

2 files changed

+17
-3
lines changed

lib/rack/utf8_sanitizer.rb

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module Rack
88
class UTF8Sanitizer
99
StringIO = ::StringIO
1010
NULL_BYTE_REGEX = /\x00/.freeze
11+
NULL_BYTE_STRING_REGEX = Regexp.new('\\\u0000').freeze
1112

1213
class NullByteInString < StandardError; end
1314

@@ -40,15 +41,15 @@ def call(env)
4041
invalid: :replace,
4142
undef: :replace)
4243
if sanitize_null_bytes
43-
input = input.gsub(NULL_BYTE_REGEX, "")
44+
input = input.gsub(NULL_BYTE_REGEX, "").gsub(NULL_BYTE_STRING_REGEX, '')
4445
end
4546
input
4647
end,
4748
exception: lambda do |input, sanitize_null_bytes: false|
4849
input.
4950
force_encoding(Encoding::ASCII_8BIT).
5051
encode!(Encoding::UTF_8)
51-
if sanitize_null_bytes && NULL_BYTE_REGEX.match?(input)
52+
if sanitize_null_bytes && (NULL_BYTE_REGEX.match?(input) || NULL_BYTE_STRING_REGEX.match?(input))
5253
raise NullByteInString
5354
end
5455
input
@@ -262,7 +263,8 @@ def sanitize_string(input)
262263
if input.is_a? String
263264
input = input.dup.force_encoding(Encoding::UTF_8)
264265

265-
if input.valid_encoding? && !(@sanitize_null_bytes && input =~ NULL_BYTE_REGEX)
266+
if input.valid_encoding? &&
267+
!(@sanitize_null_bytes && (NULL_BYTE_REGEX.match?(input) || NULL_BYTE_STRING_REGEX.match?(input)))
266268
input
267269
else
268270
@strategy.call(input, sanitize_null_bytes: @sanitize_null_bytes)

test/test_utf8_sanitizer.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,18 @@ def read
395395
end
396396
end
397397

398+
it "optionally sanitizes null bytes plain string with the replace strategy" do
399+
@app = Rack::UTF8Sanitizer.new(-> env { env }, sanitize_null_bytes: true)
400+
input = "foo=bla\xED&quux=bar" + '\u0000'
401+
@rack_input = StringIO.new input
402+
403+
sanitize_form_data do |sanitized_input|
404+
sanitized_input.encoding.should == Encoding::UTF_8
405+
sanitized_input.should.be.valid_encoding
406+
sanitized_input.should == "foo=bla%EF%BF%BD&quux=bar"
407+
end
408+
end
409+
398410
it "optionally sanitizes encoded null bytes with the replace strategy" do
399411
@app = Rack::UTF8Sanitizer.new(-> env { env }, sanitize_null_bytes: true)
400412
input = "foo=bla%ED&quux=bar%00"

0 commit comments

Comments
 (0)