Skip to content

Commit

Permalink
redact password when logging Redis URL (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
eli-darkly committed Sep 22, 2021
1 parent e998229 commit 8ed7b65
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 2 deletions.
2 changes: 1 addition & 1 deletion redis_big_segments_impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func newRedisBigSegmentStoreImpl(
impl.loggers.SetPrefix("RedisBigSegmentStore:")

if impl.pool == nil {
impl.loggers.Infof("Using URL: %s", builder.url)
logRedisURL(loggers, builder.url)
impl.pool = newPool(builder.url, builder.dialOptions)
}
return impl
Expand Down
23 changes: 22 additions & 1 deletion redis_impl.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ldredis

import (
"net/url"
"time"

r "github.com/gomodule/redigo/redis"
Expand Down Expand Up @@ -49,12 +50,32 @@ func newRedisDataStoreImpl(
impl.loggers.SetPrefix("RedisDataStore:")

if impl.pool == nil {
impl.loggers.Infof("Using URL: %s", builder.url)
logRedisURL(loggers, builder.url)
impl.pool = newPool(builder.url, builder.dialOptions)
}
return impl
}

func logRedisURL(loggers ldlog.Loggers, redisURL string) {
if parsed, err := url.Parse(redisURL); err == nil {
loggers.Infof("Using URL: %s", urlToRedactedString(parsed))
} else {
loggers.Errorf("Invalid Redis URL: %s", redisURL) // we can assume that the Redis client will also fail
}
}

// Equivalent to URL.Redacted() in Go 1.15+; currently we still support Go 1.14
func urlToRedactedString(parsed *url.URL) string {
if parsed != nil && parsed.User != nil {
if _, hasPW := parsed.User.Password(); hasPW {
transformed := *parsed
transformed.User = url.UserPassword(parsed.User.Username(), "xxxxx")
return transformed.String()
}
}
return parsed.String()
}

func (store *redisDataStoreImpl) Init(allData []ldstoretypes.SerializedCollection) error {
c := store.getConn()
defer c.Close() // nolint:errcheck
Expand Down
43 changes: 43 additions & 0 deletions redis_logging_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package ldredis

import (
"testing"

"gopkg.in/launchdarkly/go-sdk-common.v2/ldlog"
"gopkg.in/launchdarkly/go-sdk-common.v2/ldlogtest"
"gopkg.in/launchdarkly/go-server-sdk.v5/ldcomponents"
"gopkg.in/launchdarkly/go-server-sdk.v5/testhelpers"

"github.com/stretchr/testify/require"
)

func doStartupLoggingTest(t *testing.T, url string, expectedLogURL string) {
mockLog1 := ldlogtest.NewMockLog()
mockLog2 := ldlogtest.NewMockLog()
defer mockLog1.DumpIfTestFailed(t)
defer mockLog2.DumpIfTestFailed(t)
context1 := testhelpers.NewSimpleClientContext("sdk-key").
WithLogging(ldcomponents.Logging().Loggers(mockLog1.Loggers))
context2 := testhelpers.NewSimpleClientContext("sdk-key").
WithLogging(ldcomponents.Logging().Loggers(mockLog2.Loggers))

store1, err := DataStore().URL(url).CreatePersistentDataStore(context1)
require.NoError(t, err)
_ = store1.Close()
mockLog1.AssertMessageMatch(t, true, ldlog.Info, "Using URL: "+expectedLogURL)

store2, err := DataStore().URL(url).CreateBigSegmentStore(context2)
require.NoError(t, err)
_ = store2.Close()
mockLog2.AssertMessageMatch(t, true, ldlog.Info, "Using URL: "+expectedLogURL)
}

func TestURLAppearsInLogAtStartup(t *testing.T) {
doStartupLoggingTest(t, "redis://localhost:6379", "redis://localhost:6379")
doStartupLoggingTest(t, "redis://localhost:6379/1", "redis://localhost:6379/1")
}

func TestURLPasswordIsObfuscatedInLog(t *testing.T) {
doStartupLoggingTest(t, "redis://username@localhost:6379", "redis://username@localhost:6379")
doStartupLoggingTest(t, "redis://username:very-secret-password@localhost:6379", "redis://username:xxxxx@localhost:6379")
}

0 comments on commit 8ed7b65

Please sign in to comment.