mirror of
https://github.com/prometheus-community/postgres_exporter
synced 2025-04-07 17:51:33 +00:00
Ensure loggableDSN scrubs passwords in different ways
The previous implementation of the function was only scrubbing those passwords that were part of a basic http authentication method, which means it expected passwords to be provided as part of the URL. However, the password may also be specified as a parameter, or when using key-values, it may be specified as a password=value string. This commit ensures those passwords will also not be retained, but removed. Signed-off-by: Feike Steenbergen <feike@timescale.com>
This commit is contained in:
parent
1b492a6c59
commit
5b57a4d058
@ -421,3 +421,58 @@ func (s *FunctionalSuite) TestParseUserQueries(c *C) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *FunctionalSuite) TestLoggableDSN(c *C) {
|
||||
type TestCase struct {
|
||||
input string
|
||||
expected string
|
||||
}
|
||||
|
||||
cases := []TestCase{
|
||||
{
|
||||
input: "host=host.example.com user=postgres port=5432 password=s3cr3t",
|
||||
expected: "host=host.example.com user=postgres port=5432 password=PASSWORD_REMOVED",
|
||||
},
|
||||
|
||||
{
|
||||
input: "host=host.example.com user=postgres port=5432 password=\"s3cr 3t\"",
|
||||
expected: "host=host.example.com user=postgres port=5432 password=PASSWORD_REMOVED",
|
||||
},
|
||||
|
||||
{
|
||||
input: "password=abcde host=host.example.com user=postgres port=5432",
|
||||
expected: "password=PASSWORD_REMOVED host=host.example.com user=postgres port=5432",
|
||||
},
|
||||
|
||||
{
|
||||
input: "password=abcde host=host.example.com user=postgres port=5432 password=\"s3cr 3t\"",
|
||||
expected: "password=PASSWORD_REMOVED host=host.example.com user=postgres port=5432 password=PASSWORD_REMOVED",
|
||||
},
|
||||
|
||||
{
|
||||
input: "postgresql://host.example.com:5432/tsdb?user=postgres",
|
||||
expected: "postgresql://host.example.com:5432/tsdb?user=postgres",
|
||||
},
|
||||
|
||||
{
|
||||
input: "postgresql://user:s3cret@host.example.com:5432/tsdb?user=postgres",
|
||||
expected: "postgresql://user:PASSWORD_REMOVED@host.example.com:5432/tsdb?user=postgres",
|
||||
},
|
||||
|
||||
{
|
||||
input: "postgresql://host.example.com:5432/tsdb?user=postgres&password=s3cr3t",
|
||||
expected: "postgresql://host.example.com:5432/tsdb?password=PASSWORD_REMOVED&user=postgres",
|
||||
},
|
||||
|
||||
{
|
||||
input: "host=host.example.com user=postgres port=5432",
|
||||
expected: "host=host.example.com user=postgres port=5432",
|
||||
},
|
||||
}
|
||||
|
||||
for _, cs := range cases {
|
||||
loggable := loggableDSN(cs.input)
|
||||
c.Assert(loggable, Equals, cs.expected)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@ -212,10 +213,24 @@ func loggableDSN(dsn string) string {
|
||||
if err != nil {
|
||||
return "could not parse DATA_SOURCE_NAME"
|
||||
}
|
||||
|
||||
// If the DSN is not a URL it is expected to be in the `key1=value1 key2=value2` format
|
||||
if pDSN.Scheme == "" {
|
||||
re := regexp.MustCompile(`(\s?password=([^"\s]+|"[^"]+"))`)
|
||||
stripped := re.ReplaceAllString(dsn, " password=PASSWORD_REMOVED")
|
||||
return strings.TrimSpace(stripped)
|
||||
}
|
||||
|
||||
// Blank user info if not nil
|
||||
if pDSN.User != nil {
|
||||
pDSN.User = url.UserPassword(pDSN.User.Username(), "PASSWORD_REMOVED")
|
||||
}
|
||||
|
||||
// If the password is contained in a URL parameter, we should remove it there
|
||||
if q, err := url.ParseQuery(pDSN.RawQuery); err == nil && q.Has("password") {
|
||||
q.Set("password", "PASSWORD_REMOVED")
|
||||
pDSN.RawQuery = q.Encode()
|
||||
}
|
||||
|
||||
return pDSN.String()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user