From 1391731699f858ded18a3c4232957ddbad3dcbef Mon Sep 17 00:00:00 2001 From: Steffen Siering Date: Fri, 24 Feb 2017 22:42:11 +0100 Subject: [PATCH] Fix elasticsearch url parsing (#3671) use regex to check if host given contains the protocol scheme. If scheme is missing, prepend before attempting to parse the complete URL --- CHANGELOG.asciidoc | 1 + libbeat/outputs/elasticsearch/url.go | 23 +++++++---------------- libbeat/outputs/elasticsearch/url_test.go | 2 ++ 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 68251d07b3d..49c2551c7d1 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -38,6 +38,7 @@ https://github.com/elastic/beats/compare/v5.1.1...master[Check the HEAD diff] *Affecting all Beats* - Add `_id`, `_type`, `_index` and `_score` fields in the generated index pattern. {pull}3282[3282] +- Fix potential elasticsearch output URL parsing error if protocol scheme is missing. {pull}3671[3671] *Filebeat* - Always use absolute path for event and registry. {pull}3328[3328] diff --git a/libbeat/outputs/elasticsearch/url.go b/libbeat/outputs/elasticsearch/url.go index a0bed53eec3..8154e572e82 100644 --- a/libbeat/outputs/elasticsearch/url.go +++ b/libbeat/outputs/elasticsearch/url.go @@ -4,9 +4,12 @@ import ( "fmt" "net" "net/url" + "regexp" "strings" ) +var hasScheme = regexp.MustCompile(`^([a-z][a-z0-9+\-.]*)://`) + // Creates the url based on the url configuration. // Adds missing parts with defaults (scheme, host, port) func MakeURL(defaultScheme string, defaultPath string, rawURL string) (string, error) { @@ -15,6 +18,10 @@ func MakeURL(defaultScheme string, defaultPath string, rawURL string) (string, e defaultScheme = "http" } + if !hasScheme.MatchString(rawURL) { + rawURL = fmt.Sprintf("%v://%v", defaultScheme, rawURL) + } + addr, err := url.Parse(rawURL) if err != nil { return "", err @@ -24,22 +31,6 @@ func MakeURL(defaultScheme string, defaultPath string, rawURL string) (string, e host := addr.Host port := "9200" - // sanitize parse errors if url does not contain scheme - // if parse url looks funny, prepend schema and try again: - if addr.Scheme == "" || (addr.Host == "" && addr.Path == "" && addr.Opaque != "") { - rawURL = fmt.Sprintf("%v://%v", defaultScheme, rawURL) - if tmpAddr, err := url.Parse(rawURL); err == nil { - addr = tmpAddr - scheme = addr.Scheme - host = addr.Host - } else { - // If url doesn't have a scheme, host is written into path. For example: 192.168.3.7 - scheme = defaultScheme - host = addr.Path - addr.Path = "" - } - } - if host == "" { host = "localhost" } else { diff --git a/libbeat/outputs/elasticsearch/url_test.go b/libbeat/outputs/elasticsearch/url_test.go index 5deecc4907e..12d5a87c5b1 100644 --- a/libbeat/outputs/elasticsearch/url_test.go +++ b/libbeat/outputs/elasticsearch/url_test.go @@ -79,6 +79,8 @@ func TestGetUrl(t *testing.T) { "http://localhost/": "http://localhost:9200/", // no schema + hostname + "33f3600fd5c1bb599af557c36a4efb08.host": "http://33f3600fd5c1bb599af557c36a4efb08.host:9200", + "33f3600fd5c1bb599af557c36a4efb08.host:12345": "http://33f3600fd5c1bb599af557c36a4efb08.host:12345", "localhost": "http://localhost:9200", "localhost:80": "http://localhost:80", "localhost:80/": "http://localhost:80/",