Commit 588dd033 authored by Bob Van Landuyt's avatar Bob Van Landuyt

Merge branch '257822-fix-handlenullbytes-with-escaped-chars' into 'master'

Fix HandleMalformedStrings middleware

See merge request gitlab-org/gitlab!46502
parents 8720d158 b6faa5af
...@@ -26,13 +26,20 @@ module Gitlab ...@@ -26,13 +26,20 @@ module Gitlab
request = Rack::Request.new(request) request = Rack::Request.new(request)
return true if string_malformed?(request.path) return true if malformed_path?(request.path)
request.params.values.any? do |value| request.params.values.any? do |value|
param_has_null_byte?(value) param_has_null_byte?(value)
end end
end end
def malformed_path?(path)
string_malformed?(Rack::Utils.unescape(path))
rescue ArgumentError
# Rack::Utils.unescape raised this, path is malformed.
true
end
def param_has_null_byte?(value, depth = 0) def param_has_null_byte?(value, depth = 0)
# Guard against possible attack sending large amounts of nested params # Guard against possible attack sending large amounts of nested params
# Should be safe as deeply nested params are highly uncommon. # Should be safe as deeply nested params are highly uncommon.
......
...@@ -5,7 +5,9 @@ require "rack/test" ...@@ -5,7 +5,9 @@ require "rack/test"
RSpec.describe Gitlab::Middleware::HandleMalformedStrings do RSpec.describe Gitlab::Middleware::HandleMalformedStrings do
let(:null_byte) { "\u0000" } let(:null_byte) { "\u0000" }
let(:escaped_null_byte) { "%00" }
let(:invalid_string) { "mal\xC0formed" } let(:invalid_string) { "mal\xC0formed" }
let(:escaped_invalid_string) { "mal%c0formed" }
let(:error_400) { [400, { 'Content-Type' => 'text/plain' }, ['Bad Request']] } let(:error_400) { [400, { 'Content-Type' => 'text/plain' }, ['Bad Request']] }
let(:app) { double(:app) } let(:app) { double(:app) }
...@@ -30,6 +32,14 @@ RSpec.describe Gitlab::Middleware::HandleMalformedStrings do ...@@ -30,6 +32,14 @@ RSpec.describe Gitlab::Middleware::HandleMalformedStrings do
expect(subject.call(env)).to eq error_400 expect(subject.call(env)).to eq error_400
end end
it 'rejects escaped null bytes' do
# We have to create the env separately or Rack::MockRequest complains about invalid URI
env = env_for
env['PATH_INFO'] = "/someplace/withan#{escaped_null_byte}escaped nullbyte"
expect(subject.call(env)).to eq error_400
end
it 'rejects malformed strings' do it 'rejects malformed strings' do
# We have to create the env separately or Rack::MockRequest complains about invalid URI # We have to create the env separately or Rack::MockRequest complains about invalid URI
env = env_for env = env_for
...@@ -37,6 +47,14 @@ RSpec.describe Gitlab::Middleware::HandleMalformedStrings do ...@@ -37,6 +47,14 @@ RSpec.describe Gitlab::Middleware::HandleMalformedStrings do
expect(subject.call(env)).to eq error_400 expect(subject.call(env)).to eq error_400
end end
it 'rejects escaped malformed strings' do
# We have to create the env separately or Rack::MockRequest complains about invalid URI
env = env_for
env['PATH_INFO'] = "/someplace/with_an/#{escaped_invalid_string}"
expect(subject.call(env)).to eq error_400
end
end end
context 'in params' do context 'in params' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment