Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Remove '\u0000' from input when sanitizing null input
Browse files Browse the repository at this point in the history
such committed Dec 16, 2024
1 parent f2bcf86 commit 7042887
Showing 2 changed files with 17 additions and 3 deletions.
8 changes: 5 additions & 3 deletions lib/rack/utf8_sanitizer.rb
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@ module Rack
class UTF8Sanitizer
StringIO = ::StringIO
NULL_BYTE_REGEX = /\x00/.freeze
NULL_BYTE_STRING_REGEX = Regexp.new('\\\u0000').freeze

class NullByteInString < StandardError; end

@@ -40,15 +41,15 @@ def call(env)
invalid: :replace,
undef: :replace)
if sanitize_null_bytes
input = input.gsub(NULL_BYTE_REGEX, "")
input = input.gsub(NULL_BYTE_REGEX, "").gsub(NULL_BYTE_STRING_REGEX, '')
end
input
end,
exception: lambda do |input, sanitize_null_bytes: false|
input.
force_encoding(Encoding::ASCII_8BIT).
encode!(Encoding::UTF_8)
if sanitize_null_bytes && NULL_BYTE_REGEX.match?(input)
if sanitize_null_bytes && (NULL_BYTE_REGEX.match?(input) || NULL_BYTE_STRING_REGEX.match?(input))
raise NullByteInString
end
input
@@ -262,7 +263,8 @@ def sanitize_string(input)
if input.is_a? String
input = input.dup.force_encoding(Encoding::UTF_8)

if input.valid_encoding? && !(@sanitize_null_bytes && input =~ NULL_BYTE_REGEX)
if input.valid_encoding? &&
!(@sanitize_null_bytes && (NULL_BYTE_REGEX.match?(input) || NULL_BYTE_STRING_REGEX.match?(input)))
input
else
@strategy.call(input, sanitize_null_bytes: @sanitize_null_bytes)
12 changes: 12 additions & 0 deletions test/test_utf8_sanitizer.rb
Original file line number Diff line number Diff line change
@@ -395,6 +395,18 @@ def read
end
end

it "optionally sanitizes null bytes plain string with the replace strategy" do
@app = Rack::UTF8Sanitizer.new(-> env { env }, sanitize_null_bytes: true)
input = "foo=bla\xED&quux=bar" + '\u0000'
@rack_input = StringIO.new input

sanitize_form_data do |sanitized_input|
sanitized_input.encoding.should == Encoding::UTF_8
sanitized_input.should.be.valid_encoding
sanitized_input.should == "foo=bla%EF%BF%BD&quux=bar"
end
end

it "optionally sanitizes encoded null bytes with the replace strategy" do
@app = Rack::UTF8Sanitizer.new(-> env { env }, sanitize_null_bytes: true)
input = "foo=bla%ED&quux=bar%00"

0 comments on commit 7042887

Please sign in to comment.