From a3f82bd13ca8011a1fa8bfafd4676eeafa24bab4 Mon Sep 17 00:00:00 2001 From: martinohmann Date: Fri, 21 Jun 2024 07:45:25 +0200 Subject: [PATCH] fix: redact passwords in logs Fixes https://github.com/AlexxIT/go2rtc/issues/238 Replaces URLs of the format `rtsp://user:password@localhost:8554` with `rtsp://user:xxxxx@localhost:8554` in logs. This is best-effort for now and does not handle cases where passwords appear in query strings. It should be fairly easy to extend the `RedactPassword` function in the future in case there are other common password pattern that are worth handling. --- internal/expr/expr.go | 2 +- internal/streams/helpers.go | 8 ++++++++ internal/streams/helpers_test.go | 14 ++++++++++++++ internal/streams/producer.go | 10 +++++----- internal/streams/streams.go | 10 ++++++---- 5 files changed, 34 insertions(+), 10 deletions(-) create mode 100644 internal/streams/helpers_test.go diff --git a/internal/expr/expr.go b/internal/expr/expr.go index a6d1f972..b8e2c67b 100644 --- a/internal/expr/expr.go +++ b/internal/expr/expr.go @@ -17,7 +17,7 @@ func Init() { return "", err } - log.Debug().Msgf("[expr] url=%s", url) + log.Debug().Msgf("[expr] url=%s", streams.RedactPassword(url[5:])) if url = v.(string); url == "" { return "", errors.New("expr: result is empty") diff --git a/internal/streams/helpers.go b/internal/streams/helpers.go index 2ead1aa3..205dd56d 100644 --- a/internal/streams/helpers.go +++ b/internal/streams/helpers.go @@ -20,3 +20,11 @@ func ParseQuery(s string) url.Values { } return params } + +func RedactPassword(s string) string { + if u, err := url.Parse(s); err == nil { + return u.Redacted() + } + + return s +} diff --git a/internal/streams/helpers_test.go b/internal/streams/helpers_test.go new file mode 100644 index 00000000..94380c8a --- /dev/null +++ b/internal/streams/helpers_test.go @@ -0,0 +1,14 @@ +package streams + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestRedactPassword(t *testing.T) { + require.Equal(t, "not_a_url", RedactPassword("not_a_url")) + require.Equal(t, "rtsp://localhost:8554", RedactPassword("rtsp://localhost:8554")) + require.Equal(t, "rtsp://user:xxxxx@localhost:8554", RedactPassword("rtsp://user:password@localhost:8554")) + require.Equal(t, "rtsp://:xxxxx@localhost:8554", RedactPassword("rtsp://:password@localhost:8554")) +} diff --git a/internal/streams/producer.go b/internal/streams/producer.go index 09e2dcc5..83d2424f 100644 --- a/internal/streams/producer.go +++ b/internal/streams/producer.go @@ -149,7 +149,7 @@ func (p *Producer) start() { return } - log.Debug().Msgf("[streams] start producer url=%s", p.url) + log.Debug().Msgf("[streams] start producer url=%s", RedactPassword(p.url)) p.state = stateStart p.workerID++ @@ -167,7 +167,7 @@ func (p *Producer) worker(conn core.Producer, workerID int) { return } - log.Warn().Err(err).Str("url", p.url).Caller().Send() + log.Warn().Err(err).Str("url", RedactPassword(p.url)).Caller().Send() } p.reconnect(workerID, 0) @@ -178,11 +178,11 @@ func (p *Producer) reconnect(workerID, retry int) { defer p.mu.Unlock() if p.workerID != workerID { - log.Trace().Msgf("[streams] stop reconnect url=%s", p.url) + log.Trace().Msgf("[streams] stop reconnect url=%s", RedactPassword(p.url)) return } - log.Debug().Msgf("[streams] retry=%d to url=%s", retry, p.url) + log.Debug().Msgf("[streams] retry=%d to url=%s", retry, RedactPassword(p.url)) conn, err := GetProducer(p.url) if err != nil { @@ -257,7 +257,7 @@ func (p *Producer) stop() { p.workerID++ } - log.Debug().Msgf("[streams] stop producer url=%s", p.url) + log.Debug().Msgf("[streams] stop producer url=%s", RedactPassword(p.url)) if p.conn != nil { _ = p.conn.Stop() diff --git a/internal/streams/streams.go b/internal/streams/streams.go index ff0f5654..8e3da458 100644 --- a/internal/streams/streams.go +++ b/internal/streams/streams.go @@ -119,7 +119,7 @@ func GetOrPatch(query url.Values) *Stream { // check if name param provided if name := query.Get("name"); name != "" { - log.Info().Msgf("[streams] create new stream url=%s", source) + log.Info().Msgf("[streams] create new stream url=%s", RedactPassword(source)) return Patch(name, source) } @@ -143,6 +143,8 @@ func Delete(id string) { delete(streams, id) } -var log zerolog.Logger -var streams = map[string]*Stream{} -var streamsMu sync.Mutex +var ( + log zerolog.Logger + streams = map[string]*Stream{} + streamsMu sync.Mutex +)