From 0ebbb394930d73cc3133155e262fb821a59dec23 Mon Sep 17 00:00:00 2001 From: Rob Bavey Date: Thu, 7 Feb 2019 11:04:59 -0500 Subject: [PATCH] Better handle malformed URIs Raise an error if a URI has inadvertently been supplied without a host Fixes #10414 --- logstash-core/lib/logstash/util/safe_uri.rb | 3 +- .../spec/logstash/util/safe_uri_spec.rb | 78 +++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/logstash-core/lib/logstash/util/safe_uri.rb b/logstash-core/lib/logstash/util/safe_uri.rb index 0513833ac..736711ebb 100644 --- a/logstash-core/lib/logstash/util/safe_uri.rb +++ b/logstash-core/lib/logstash/util/safe_uri.rb @@ -14,7 +14,7 @@ class LogStash::Util::SafeURI attr_reader :uri public - def initialize(arg) + def initialize(arg, requires_host=true) @uri = case arg when String arg = "//#{arg}" if HOSTNAME_PORT_REGEX.match(arg) @@ -26,6 +26,7 @@ class LogStash::Util::SafeURI else raise ArgumentError, "Expected a string, java.net.URI, or URI, got a #{arg.class} creating a URL" end + raise ArgumentError, "URI is not valid - host is not specified" if requires_host && @uri.host.nil? end def to_s diff --git a/logstash-core/spec/logstash/util/safe_uri_spec.rb b/logstash-core/spec/logstash/util/safe_uri_spec.rb index 12962ccff..83cccd160 100644 --- a/logstash-core/spec/logstash/util/safe_uri_spec.rb +++ b/logstash-core/spec/logstash/util/safe_uri_spec.rb @@ -32,5 +32,83 @@ module LogStash module Util end end end + + describe "#initialize" do + context 'when host is required' do + MALFORMED_URIS = ['http:/user:pass@localhost:9600', 'http:/localhost', 'http:/localhost:9600', 'h;localhost', 'http:://localhost'] + + context 'malformed uris via string' do + MALFORMED_URIS.each do |arg| + it "#{arg}: should raise an error" do + expect{LogStash::Util::SafeURI.new(arg)}.to raise_error(ArgumentError) + end + end + end + + context 'malformed uris via java.net.URI' do + MALFORMED_URIS.each do |arg| + it "#{arg}: should raise an error" do + java_uri = java.net.URI.new(arg) + expect{LogStash::Util::SafeURI.new(java_uri)}.to raise_error(ArgumentError) + end + end + end + + context 'malformed uris via Ruby URI' do + MALFORMED_URIS.each do |arg| + it "#{arg}: should raise an error" do + ruby_uri = URI.parse(arg) + expect{LogStash::Util::SafeURI.new(ruby_uri)}.to raise_error(ArgumentError) + end + end + end + + context 'uris with a valid host' do + ['http://user:pass@notlocalhost:9600', 'http://notlocalhost', 'https://notlocalhost:9600', '//notlocalhost', 'notlocalhost', 'notlocalhost:9200'].each do |arg| + it "#{arg}: should resolve host correctly" do + expect(LogStash::Util::SafeURI.new(arg).host).to eq('notlocalhost') + end + end + end + end + + context 'when host is not required' do + MALFORMED_URIS = ['http:/user:pass@localhost:9600', 'http:/localhost', 'http:/localhost:9600', 'h;localhost', 'http:://localhost'] + + context 'malformed uris via string' do + MALFORMED_URIS.each do |arg| + it "#{arg}: should not raise an error" do + expect{LogStash::Util::SafeURI.new(arg, false)}.not_to raise_error + end + end + end + + context 'malformed uris via java.net.URI' do + MALFORMED_URIS.each do |arg| + it "#{arg}: should not raise an error" do + java_uri = java.net.URI.new(arg) + expect{LogStash::Util::SafeURI.new(java_uri, false)}.not_to raise_error + end + end + end + + context 'malformed uris via Ruby URI' do + MALFORMED_URIS.each do |arg| + it "#{arg}: should not raise an error" do + ruby_uri = URI.parse(arg) + expect{LogStash::Util::SafeURI.new(ruby_uri, false)}.not_to raise_error + end + end + end + + context 'uris with a valid host' do + ['http://user:pass@notlocalhost:9600', 'http://notlocalhost', 'https://notlocalhost:9600', '//notlocalhost', 'notlocalhost', 'notlocalhost:9200'].each do |arg| + it "#{arg}: should resolve host correctly" do + expect(LogStash::Util::SafeURI.new(arg, false).host).to eq('notlocalhost') + end + end + end + end + end end end end