diff --git a/plugins/outputs/prometheus_client/README.md b/plugins/outputs/prometheus_client/README.md index af86b9822607f..d42eecfd429bd 100644 --- a/plugins/outputs/prometheus_client/README.md +++ b/plugins/outputs/prometheus_client/README.md @@ -15,9 +15,8 @@ This plugin starts a [Prometheus](https://prometheus.io/) Client, it exposes all tls_key = "/etc/ssl/telegraf.key" # Use http basic authentication - basic_auth = true - username = "Foo" - password = "Bar" + basic_username = "Foo" + basic_password = "Bar" # Path to publish the metrics on, defaults to /metrics path = "/metrics" diff --git a/plugins/outputs/prometheus_client/prometheus_client.go b/plugins/outputs/prometheus_client/prometheus_client.go index f44071500d5c6..34bfd27bf80cc 100644 --- a/plugins/outputs/prometheus_client/prometheus_client.go +++ b/plugins/outputs/prometheus_client/prometheus_client.go @@ -2,6 +2,7 @@ package prometheus_client import ( "context" + "crypto/subtle" "crypto/tls" "fmt" "log" @@ -56,9 +57,8 @@ type PrometheusClient struct { Listen string TLSCert string `toml:"tls_cert"` TLSKey string `toml:"tls_key"` - BasicAuth bool `toml:"basic_auth"` - Username string `toml:"username"` - Password string `toml:"password"` + BasicUsername string `toml:"basic_username"` + BasicPassword string `toml:"basic_password"` ExpirationInterval internal.Duration `toml:"expiration_interval"` Path string `toml:"path"` CollectorsExclude []string `toml:"collectors_exclude"` @@ -81,9 +81,8 @@ var sampleConfig = ` #tls_key = "/etc/ssl/telegraf.key" ## Use http basic authentication - # basic_auth = true - username = "Foo" - password = "Bar" + #basic_username = "Foo" + #basic_password = "Bar" ## Interval to expire metrics and not deliver to prometheus, 0 == no expiration # expiration_interval = "60s" @@ -109,16 +108,13 @@ func (p *PrometheusClient) getTLSConfig() *tls.Config { func (p *PrometheusClient) basicAuth(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if p.BasicAuth { + if p.BasicUsername != "" && p.BasicPassword != "" { w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`) username, password, ok := r.BasicAuth() - if !ok { - http.Error(w, "Not authorized", 401) - return - } - - if username != p.Username || password != p.Password { + if !ok || + subtle.ConstantTimeCompare([]byte(username), []byte(p.BasicUsername)) != 1 || + subtle.ConstantTimeCompare([]byte(password), []byte(p.BasicPassword)) != 1 { http.Error(w, "Not authorized", 401) return }