diff --git a/mysql/gcpmysql/gcpmysql.go b/mysql/gcpmysql/gcpmysql.go index 87588804c5..19d96cd326 100644 --- a/mysql/gcpmysql/gcpmysql.go +++ b/mysql/gcpmysql/gcpmysql.go @@ -77,7 +77,7 @@ func (o *lazyCredsOpener) OpenMySQLURL(ctx context.Context, u *url.URL) (*sql.DB o.opener = &URLOpener{CertSource: certSource} }) if o.err != nil { - return nil, fmt.Errorf("gcpmysql open %v: %v", u, o.err) + return nil, fmt.Errorf("gcpmysql open %v: %v", u.Redacted(), o.err) } return o.opener.OpenMySQLURL(ctx, u) } diff --git a/mysql/gcpmysql/gcpmysql_test.go b/mysql/gcpmysql/gcpmysql_test.go index db41a15b2b..cc1db30e51 100644 --- a/mysql/gcpmysql/gcpmysql_test.go +++ b/mysql/gcpmysql/gcpmysql_test.go @@ -19,6 +19,7 @@ import ( "fmt" "net/url" "reflect" + "strings" "testing" drvr "github.com/go-sql-driver/mysql" @@ -26,6 +27,22 @@ import ( "gocloud.dev/mysql" ) +func TestOpenMySQLURLDoesNotLeakPasswordOnCredentialsFailure(t *testing.T) { + const password = "S3cr3tDBPassw0rd" + u, err := url.Parse(fmt.Sprintf("gcpmysql://dbuser:%s@myproject/us-central1/myinstance/mydb", password)) + if err != nil { + t.Fatalf("failed to parse URL: %v", err) + } + o := new(lazyCredsOpener) + _, err = o.OpenMySQLURL(context.Background(), u) + if err == nil { + t.Skip("Application Default Credentials are available in this environment; skipping negative-path test") + } + if strings.Contains(err.Error(), password) { + t.Errorf("OpenMySQLURL error contains the raw password: %q", err.Error()) + } +} + func TestOpen(t *testing.T) { // This test will be skipped unless the project is set up with Terraform. // Before running go test, run in this directory: