From f8200870506b1130860aeee525faba5447628762 Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Fri, 15 Mar 2024 14:20:28 +1300 Subject: [PATCH 1/2] fix: return 400 if uri is bad --- lib/rack/canonical_host.rb | 2 ++ spec/rack/canonical_host_spec.rb | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/lib/rack/canonical_host.rb b/lib/rack/canonical_host.rb index 5091b09..e09a5e2 100644 --- a/lib/rack/canonical_host.rb +++ b/lib/rack/canonical_host.rb @@ -20,6 +20,8 @@ def call(env) else redirect.response end + rescue Addressable::URI::InvalidURIError + [400, { Rack::CONTENT_TYPE => "text/plain", Rack::CONTENT_LENGTH => "0" }, []] end protected diff --git a/spec/rack/canonical_host_spec.rb b/spec/rack/canonical_host_spec.rb index dcde709..b94b4d0 100644 --- a/spec/rack/canonical_host_spec.rb +++ b/spec/rack/canonical_host_spec.rb @@ -98,6 +98,21 @@ def call_app it_behaves_like 'a non-matching request' end + + context 'which is an invalid uri' do + let(:headers) { { 'HTTP_X_FORWARDED_HOST' => '[${jndi:ldap://172.16.26.190:52314/nessus}]/' } } + + it { should_not be_redirect } + + it { expect(response[0]).to be 400 } + + it 'does not call the inner app' do + expect(inner_app).to_not receive(:call) + call_app + end + + it { expect(response).to_not have_header('cache-control') } + end end context 'without a host' do From 438a208f9b0b061b460b8d04a4e79bcbc56a95c1 Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Fri, 15 Mar 2024 14:38:58 +1300 Subject: [PATCH 2/2] fix: only catch our invalid uri errors --- lib/rack/canonical_host.rb | 12 ++++++------ spec/rack/canonical_host_spec.rb | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/lib/rack/canonical_host.rb b/lib/rack/canonical_host.rb index e09a5e2..5e6cfae 100644 --- a/lib/rack/canonical_host.rb +++ b/lib/rack/canonical_host.rb @@ -15,13 +15,13 @@ def call(env) host = evaluate_host(env) redirect = Redirect.new(env, host, options) - if redirect.canonical? - app.call(env) - else - redirect.response + begin + return redirect.response unless redirect.canonical? + rescue Addressable::URI::InvalidURIError + return [400, { Rack::CONTENT_TYPE => "text/plain", Rack::CONTENT_LENGTH => "0" }, []] end - rescue Addressable::URI::InvalidURIError - [400, { Rack::CONTENT_TYPE => "text/plain", Rack::CONTENT_LENGTH => "0" }, []] + + app.call(env) end protected diff --git a/spec/rack/canonical_host_spec.rb b/spec/rack/canonical_host_spec.rb index b94b4d0..fcc2e44 100644 --- a/spec/rack/canonical_host_spec.rb +++ b/spec/rack/canonical_host_spec.rb @@ -84,6 +84,20 @@ def call_app end end + + context 'when the app happens to have an invalid uri error' do + before do + allow(inner_app) + .to receive(:call) + .with(env) + .and_raise(Addressable::URI::InvalidURIError) + end + + it 'explodes as expected' do + expect { call_app }.to raise_error(Addressable::URI::InvalidURIError) + end + end + context 'with an X-Forwarded-Host' do let(:url) { 'http://proxy.test/full/path' }