From f5e7ce83f3224b731c66e4f31d55f47b899af3c7 Mon Sep 17 00:00:00 2001 From: Simon Gottschlag Date: Wed, 1 Mar 2023 10:17:52 +0100 Subject: [PATCH] Redact git secret from logs (#35) --- src/source/git.go | 26 ++++++++++++++++++++++++-- src/source/git_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/source/git.go b/src/source/git.go index d738e70..139e1c9 100644 --- a/src/source/git.go +++ b/src/source/git.go @@ -6,6 +6,7 @@ import ( "net/url" "os" "path/filepath" + "strings" "github.com/fluxcd/pkg/git" "github.com/fluxcd/pkg/git/gogit" @@ -81,8 +82,9 @@ func (s *GitSource) checkout(ctx context.Context) (*map[string][]byte, string, e } commit, err := gitReader.Clone(ctx, s.cfg.GitUrl, cloneOpts) if err != nil { - log.V(1).Error(err, "failed to clone") - return nil, "", err + redactedErr := redactGitSecretFromError(s.cfg.GitUrl, err) + log.V(1).Error(redactedErr, "failed to clone") + return nil, "", redactedErr } log.V(1).Info("commit data", "ShortMessage", commit.ShortMessage(), "String", commit.String(), "commit", commit) @@ -108,6 +110,26 @@ func (s *GitSource) checkout(ctx context.Context) (*map[string][]byte, string, e return yamlFiles, revision, nil } +func redactGitSecretFromError(gitUrl string, inputErr error) error { + parsedGitUrl, err := url.Parse(gitUrl) + if err != nil { + return inputErr + } + + gitSecret, ok := parsedGitUrl.User.Password() + if !ok { + return inputErr + } + + if gitSecret == "" { + return inputErr + } + + inputErrString := inputErr.Error() + inputErrStringRedacted := strings.ReplaceAll(inputErrString, gitSecret, "redacted") + return fmt.Errorf(inputErrStringRedacted) +} + func createTemporaryDirectory(ctx context.Context, path string) (string, func(), error) { log := logr.FromContextOrDiscard(ctx) diff --git a/src/source/git_test.go b/src/source/git_test.go index 6a01b95..6a17303 100644 --- a/src/source/git_test.go +++ b/src/source/git_test.go @@ -164,3 +164,30 @@ func testCommitFile(t *testing.T, ctx context.Context, ggc *gg.Client, path, con return newRef, nil } + +func TestRedactGitSecretFromError(t *testing.T) { + cases := []struct { + testDescription string + gitUrl string + inputErrorString string + expectedResult string + }{ + { + testDescription: "redact secret", + // secretlint-disable + gitUrl: "https://foo:supersecret@foobar.net", + // secretlint-disable + inputErrorString: "unable to clone https://foo:supersecret@foobar.net", + // secretlint-disable + expectedResult: "unable to clone https://foo:redacted@foobar.net", + }, + } + + for i, c := range cases { + t.Logf("Test #%d: %s", i, c.testDescription) + inputError := fmt.Errorf(c.inputErrorString) + result := redactGitSecretFromError(c.gitUrl, inputError) + require.Equal(t, c.expectedResult, result.Error()) + } + +}