From 427d4df4efd76e12384dea852eb7531dba18c576 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20Gond=C5=BEa?= Date: Wed, 27 Nov 2024 22:23:32 +0100 Subject: [PATCH] feat(cmd): Sanitize all verbose logging calls to redact the secrets --- pkg/auth/vault/approle.go | 11 +++++++---- pkg/auth/vault/github.go | 8 ++++---- pkg/auth/vault/kubernetes.go | 11 +++++++---- pkg/auth/vault/userpass.go | 11 +++++++---- pkg/backends/awssecretsmanager.go | 2 +- pkg/backends/azurekeyvault.go | 8 ++++---- pkg/backends/delineasecretsmanager.go | 4 ++-- pkg/backends/gcpsecretmanager.go | 2 +- pkg/backends/ibmsecretsmanager.go | 8 ++++---- pkg/backends/keepersecretsmanager.go | 2 +- pkg/backends/kubernetessecret.go | 4 ++-- pkg/backends/localsecretmanager.go | 2 +- pkg/backends/onepasswordconnect.go | 2 +- pkg/backends/vault.go | 2 +- pkg/backends/yandexcloudlockbox.go | 2 +- pkg/kube/util.go | 4 ++-- 16 files changed, 46 insertions(+), 37 deletions(-) diff --git a/pkg/auth/vault/approle.go b/pkg/auth/vault/approle.go index 913f2c66..26d77174 100644 --- a/pkg/auth/vault/approle.go +++ b/pkg/auth/vault/approle.go @@ -35,7 +35,7 @@ func NewAppRoleAuth(roleID, secretID, mountPath string) *AppRoleAuth { func (a *AppRoleAuth) Authenticate(vaultClient *api.Client) error { err := utils.LoginWithCachedToken(vaultClient, fmt.Sprintf("approle_%s", a.RoleID)) if err != nil { - utils.VerboseToStdErr("Hashicorp Vault cannot retrieve cached token: %v. Generating a new one", err) + utils.VerboseToStdErr("Hashicorp Vault cannot retrieve cached token: %v. Generating a new one", utils.SanitizeUnsafe(err)) } else { return nil } @@ -45,18 +45,21 @@ func (a *AppRoleAuth) Authenticate(vaultClient *api.Client) error { "secret_id": a.SecretID, } - utils.VerboseToStdErr("Hashicorp Vault authenticating with role ID %s and secret ID %s at path %s", a.RoleID, a.SecretID, a.MountPath) + utils.VerboseToStdErr( + "Hashicorp Vault authenticating with role ID %s and secret ID %s at path %s", + utils.SanitizeUnsafe(a.RoleID), utils.SanitizeUnsafe(a.SecretID), a.MountPath, + ) data, err := vaultClient.Logical().Write(fmt.Sprintf("%s/login", a.MountPath), payload) if err != nil { return err } - utils.VerboseToStdErr("Hashicorp Vault authentication response: %v", data) + utils.VerboseToStdErr("Hashicorp Vault authentication response: %v", utils.SanitizeUnsafe(data)) // If we cannot write the Vault token, we'll just have to login next time. Nothing showstopping. err = utils.SetToken(vaultClient, fmt.Sprintf("approle_%s", a.RoleID), data.Auth.ClientToken) if err != nil { - utils.VerboseToStdErr("Hashicorp Vault cannot cache token for future runs: %v", err) + utils.VerboseToStdErr("Hashicorp Vault cannot cache token for future runs: %v", utils.SanitizeUnsafe(err)) } return nil diff --git a/pkg/auth/vault/github.go b/pkg/auth/vault/github.go index dfd6403e..d0464e15 100644 --- a/pkg/auth/vault/github.go +++ b/pkg/auth/vault/github.go @@ -34,7 +34,7 @@ func NewGithubAuth(token, mountPath string) *GithubAuth { func (g *GithubAuth) Authenticate(vaultClient *api.Client) error { err := utils.LoginWithCachedToken(vaultClient, "github") if err != nil { - utils.VerboseToStdErr("Hashicorp Vault cannot retrieve cached token: %v. Generating a new one", err) + utils.VerboseToStdErr("Hashicorp Vault cannot retrieve cached token: %v. Generating a new one", utils.SanitizeUnsafe(err)) } else { return nil } @@ -43,18 +43,18 @@ func (g *GithubAuth) Authenticate(vaultClient *api.Client) error { "token": g.AccessToken, } - utils.VerboseToStdErr("Hashicorp Vault authenticating with Github token %s", g.AccessToken) + utils.VerboseToStdErr("Hashicorp Vault authenticating with Github token %s", utils.SanitizeUnsafe(g.AccessToken)) data, err := vaultClient.Logical().Write(fmt.Sprintf("%s/login", g.MountPath), payload) if err != nil { return err } - utils.VerboseToStdErr("Hashicorp Vault authentication response: %v", data) + utils.VerboseToStdErr("Hashicorp Vault authentication response: %v", utils.SanitizeUnsafe(data)) // If we cannot write the Vault token, we'll just have to login next time. Nothing showstopping. err = utils.SetToken(vaultClient, "github", data.Auth.ClientToken) if err != nil { - utils.VerboseToStdErr("Hashicorp Vault cannot cache token for future runs: %v", err) + utils.VerboseToStdErr("Hashicorp Vault cannot cache token for future runs: %v", utils.SanitizeUnsafe(err)) } return nil diff --git a/pkg/auth/vault/kubernetes.go b/pkg/auth/vault/kubernetes.go index 196404df..7bb5cff8 100644 --- a/pkg/auth/vault/kubernetes.go +++ b/pkg/auth/vault/kubernetes.go @@ -41,7 +41,7 @@ func NewK8sAuth(role, mountPath, tokenPath string) *K8sAuth { func (k *K8sAuth) Authenticate(vaultClient *api.Client) error { err := utils.LoginWithCachedToken(vaultClient, "kubernetes") if err != nil { - utils.VerboseToStdErr("Hashicorp Vault cannot retrieve cached token: %v. Generating a new one", err) + utils.VerboseToStdErr("Hashicorp Vault cannot retrieve cached token: %v. Generating a new one", utils.SanitizeUnsafe(err)) } else { return nil } @@ -61,18 +61,21 @@ func (k *K8sAuth) Authenticate(vaultClient *api.Client) error { kubeAuthPath = k.MountPath } - utils.VerboseToStdErr("Hashicorp Vault authenticating with Vault role %s using Kubernetes service account token %s read from %s", k.Role, serviceAccountFile, token) + utils.VerboseToStdErr( + "Hashicorp Vault authenticating with Vault role %s using Kubernetes service account token %s read from %s", + k.Role, serviceAccountFile, utils.SanitizeUnsafe(token), + ) data, err := vaultClient.Logical().Write(fmt.Sprintf("%s/login", kubeAuthPath), payload) if err != nil { return err } - utils.VerboseToStdErr("Hashicorp Vault authentication response: %v", data) + utils.VerboseToStdErr("Hashicorp Vault authentication response: %v", utils.SanitizeUnsafe(data)) // If we cannot write the Vault token, we'll just have to login next time. Nothing showstopping. err = utils.SetToken(vaultClient, "kubernetes", data.Auth.ClientToken) if err != nil { - utils.VerboseToStdErr("Hashicorp Vault cannot cache token for future runs: %v", err) + utils.VerboseToStdErr("Hashicorp Vault cannot cache token for future runs: %v", utils.SanitizeUnsafe(err)) } return nil diff --git a/pkg/auth/vault/userpass.go b/pkg/auth/vault/userpass.go index 027d20f9..3b9e3d9b 100644 --- a/pkg/auth/vault/userpass.go +++ b/pkg/auth/vault/userpass.go @@ -35,7 +35,7 @@ func NewUserPassAuth(username, password, mountPath string) *UserPassAuth { func (a *UserPassAuth) Authenticate(vaultClient *api.Client) error { err := utils.LoginWithCachedToken(vaultClient, fmt.Sprintf("userpass_%s", a.Username)) if err != nil { - utils.VerboseToStdErr("Hashicorp Vault cannot retrieve cached token: %v. Generating a new one", err) + utils.VerboseToStdErr("Hashicorp Vault cannot retrieve cached token: %v. Generating a new one", utils.SanitizeUnsafe(err)) } else { return nil } @@ -44,17 +44,20 @@ func (a *UserPassAuth) Authenticate(vaultClient *api.Client) error { "password": a.Password, } - utils.VerboseToStdErr("Hashicorp Vault authenticating with username %s and password %s", a.Username, a.Password) + utils.VerboseToStdErr( + "Hashicorp Vault authenticating with username %s and password %s", + utils.SanitizeUnsafe(a.Username), utils.SanitizeUnsafe(a.Password), + ) data, err := vaultClient.Logical().Write(fmt.Sprintf("%s/login/%s", a.MountPath, a.Username), payload) if err != nil { return err } - utils.VerboseToStdErr("Hashicorp Vault authentication response: %v", data) + utils.VerboseToStdErr("Hashicorp Vault authentication response: %v", utils.SanitizeUnsafe(data)) // If we cannot write the Vault token, we'll just have to login next time. Nothing showstopping. if err = utils.SetToken(vaultClient, fmt.Sprintf("userpass_%s", a.Username), data.Auth.ClientToken); err != nil { - utils.VerboseToStdErr("Hashicorp Vault cannot cache token for future runs: %v", err) + utils.VerboseToStdErr("Hashicorp Vault cannot cache token for future runs: %v", utils.SanitizeUnsafe(err)) } return nil diff --git a/pkg/backends/awssecretsmanager.go b/pkg/backends/awssecretsmanager.go index 08efb77c..981da225 100644 --- a/pkg/backends/awssecretsmanager.go +++ b/pkg/backends/awssecretsmanager.go @@ -70,7 +70,7 @@ func (a *AWSSecretsManager) GetSecrets(path string, version string, annotations return nil, err } - utils.VerboseToStdErr("AWS Secrets Manager get secret response %v", result) + utils.VerboseToStdErr("AWS Secrets Manager get secret response %v", utils.SanitizeUnsafe(result)) var dat map[string]interface{} diff --git a/pkg/backends/azurekeyvault.go b/pkg/backends/azurekeyvault.go index ec68ad29..0d96be36 100644 --- a/pkg/backends/azurekeyvault.go +++ b/pkg/backends/azurekeyvault.go @@ -73,16 +73,16 @@ func (a *AzureKeyVault) GetSecrets(kvpath string, version string, _ map[string]s if err != nil { return nil, err } - utils.VerboseToStdErr("Azure Key Vault get secret response %v", secret) + utils.VerboseToStdErr("Azure Key Vault get secret response %v", utils.SanitizeUnsafe(secret)) data[name] = *secret.Value } else { verboseOptionalVersion("Azure Key Vault getting secret %s from vault %s", version, name, kvpath) secret, err := client.GetSecret(ctx, name, version, nil) if err != nil || !*secretVersion.Attributes.Enabled { - utils.VerboseToStdErr("Azure Key Vault get versioned secret not found %s", err) + utils.VerboseToStdErr("Azure Key Vault get versioned secret not found %s", utils.SanitizeUnsafe(err)) continue } - utils.VerboseToStdErr("Azure Key Vault get versioned secret response %v", secret) + utils.VerboseToStdErr("Azure Key Vault get versioned secret response %v", utils.SanitizeUnsafe(secret)) data[name] = *secret.Value } } @@ -110,7 +110,7 @@ func (a *AzureKeyVault) GetIndividualSecret(kvpath, secret, version string, anno return nil, err } - utils.VerboseToStdErr("Azure Key Vault get individual secret response %v", data) + utils.VerboseToStdErr("Azure Key Vault get individual secret response %v", utils.SanitizeUnsafe(data)) return *data.Value, nil } diff --git a/pkg/backends/delineasecretsmanager.go b/pkg/backends/delineasecretsmanager.go index fbf398dc..2592b227 100644 --- a/pkg/backends/delineasecretsmanager.go +++ b/pkg/backends/delineasecretsmanager.go @@ -60,7 +60,7 @@ func (a *DelineaSecretServer) GetSecrets(path string, version string, annotation return nil, fmt.Errorf("could not decode secret json %s", secret_json) } - utils.VerboseToStdErr("Delinea Secret Server decoding json %s", secret) + utils.VerboseToStdErr("Delinea Secret Server decoding json %s", utils.SanitizeUnsafe(secret)) secret_map := make(map[string]interface{}) @@ -69,7 +69,7 @@ func (a *DelineaSecretServer) GetSecrets(path string, version string, annotation secret_map[secret.Fields[index].Slug] = secret.Fields[index].ItemValue } - utils.VerboseToStdErr("Delinea Secret Server constructed map %s", secret_map) + utils.VerboseToStdErr("Delinea Secret Server constructed map %s", utils.SanitizeUnsafe(secret_map)) return secret_map, nil } diff --git a/pkg/backends/gcpsecretmanager.go b/pkg/backends/gcpsecretmanager.go index e18e97a7..f7d0f3c0 100644 --- a/pkg/backends/gcpsecretmanager.go +++ b/pkg/backends/gcpsecretmanager.go @@ -57,7 +57,7 @@ func (a *GCPSecretManager) GetSecrets(path string, version string, annotations m return nil, fmt.Errorf("Could not find secret: %v", err) } - utils.VerboseToStdErr("GCP Secret Manager access secret version response %v", result) + utils.VerboseToStdErr("GCP Secret Manager access secret version response %v", utils.SanitizeUnsafe(result)) data := make(map[string]interface{}) diff --git a/pkg/backends/ibmsecretsmanager.go b/pkg/backends/ibmsecretsmanager.go index c6d34f8c..4c0abc5f 100644 --- a/pkg/backends/ibmsecretsmanager.go +++ b/pkg/backends/ibmsecretsmanager.go @@ -384,7 +384,7 @@ func (i *IBMSecretsManager) getSecretVersionedOrNot(id, stype, version string) ( return nil, fmt.Errorf("Could not retrieve secret %s after %d retries, statuscode %d", id, types.IBMMaxRetries, httpResponse.GetStatusCode()) } - utils.VerboseToStdErr("IBM Cloud Secrets Manager get versioned secret %s HTTP response: %v", id, httpResponse) + utils.VerboseToStdErr("IBM Cloud Secrets Manager get versioned secret %s HTTP response: %v", id, utils.SanitizeUnsafe(httpResponse)) result, err = NewIBMVersionedSecretData(secretVersion).GetSecret() if err != nil { @@ -402,7 +402,7 @@ func (i *IBMSecretsManager) getSecretVersionedOrNot(id, stype, version string) ( return nil, fmt.Errorf("Could not retrieve secret %s after %d retries, statuscode %d", id, types.IBMMaxRetries, httpResponse.GetStatusCode()) } - utils.VerboseToStdErr("IBM Cloud Secrets Manager get unversioned secret %s HTTP response: %v", id, httpResponse) + utils.VerboseToStdErr("IBM Cloud Secrets Manager get unversioned secret %s HTTP response: %v", id, utils.SanitizeUnsafe(httpResponse)) result, err = NewIBMSecretData(secretRes).GetSecret() if err != nil { @@ -500,7 +500,7 @@ func (i *IBMSecretsManager) listSecretsInGroup(groupId, secretType string) (map[ return nil, fmt.Errorf("Could not list secrets for secret group %s: %d\n%s", groupId, details.GetStatusCode(), details.String()) } - utils.VerboseToStdErr("IBM Cloud Secrets Manager list secrets in group HTTP response: %v", details) + utils.VerboseToStdErr("IBM Cloud Secrets Manager list secrets in group HTTP response: %v", utils.SanitizeUnsafe(details)) for _, secret := range res.Secrets { var name, ttype string @@ -508,7 +508,7 @@ func (i *IBMSecretsManager) listSecretsInGroup(groupId, secretType string) (map[ data, err := v.GetMetadata() if err != nil { - utils.VerboseToStdErr("Skipping a secret in group %s: %s", groupId, err) + utils.VerboseToStdErr("Skipping a secret in group %s: %s", groupId, utils.SanitizeUnsafe(err)) } name = data["name"] diff --git a/pkg/backends/keepersecretsmanager.go b/pkg/backends/keepersecretsmanager.go index d2e3d3e3..7a983111 100644 --- a/pkg/backends/keepersecretsmanager.go +++ b/pkg/backends/keepersecretsmanager.go @@ -140,7 +140,7 @@ func (a *KeeperSecretsManager) GetSecrets(path string, version string, annotatio } } - utils.VerboseToStdErr("Keeper Secrets Manager constructed map %s", secretMap) + utils.VerboseToStdErr("Keeper Secrets Manager constructed map %s", utils.SanitizeUnsafe(secretMap)) return secretMap, nil diff --git a/pkg/backends/kubernetessecret.go b/pkg/backends/kubernetessecret.go index fadb1fe7..12e87a16 100644 --- a/pkg/backends/kubernetessecret.go +++ b/pkg/backends/kubernetessecret.go @@ -43,7 +43,7 @@ func (k *KubernetesSecret) GetSecrets(path string, version string, annotations m out[k] = string(v) } - utils.VerboseToStdErr("K8s Secret get secret response: %v", out) + utils.VerboseToStdErr("K8s Secret get secret response: %v", utils.SanitizeUnsafe(out)) return out, nil } @@ -51,7 +51,7 @@ func (k *KubernetesSecret) GetSecrets(path string, version string, annotations m // Kubernetes Secrets can only be wholly read, // So, we use GetSecrets and extract the specific placeholder we want func (k *KubernetesSecret) GetIndividualSecret(path, secret, version string, annotations map[string]string) (interface{}, error) { - utils.VerboseToStdErr("K8s Secret getting secret %s and key %s", path, secret) + utils.VerboseToStdErr("K8s Secret getting secret %s and key %s", path, utils.SanitizeUnsafe(secret)) data, err := k.GetSecrets(path, version, annotations) if err != nil { return nil, err diff --git a/pkg/backends/localsecretmanager.go b/pkg/backends/localsecretmanager.go index 5fa15e42..db37dcf7 100644 --- a/pkg/backends/localsecretmanager.go +++ b/pkg/backends/localsecretmanager.go @@ -32,7 +32,7 @@ func (a *LocalSecretManager) GetSecrets(path string, version string, annotations utils.VerboseToStdErr("Local secret manager getting secret %s at version %s", path, version) cleartext, err := a.Decrypt(path, "yaml") - utils.VerboseToStdErr("Local secret manager get secret response: %v", cleartext) + utils.VerboseToStdErr("Local secret manager get secret response: %v", utils.SanitizeUnsafe(cleartext)) var dat map[string]interface{} diff --git a/pkg/backends/onepasswordconnect.go b/pkg/backends/onepasswordconnect.go index 8c15a1f8..227efcf1 100644 --- a/pkg/backends/onepasswordconnect.go +++ b/pkg/backends/onepasswordconnect.go @@ -37,7 +37,7 @@ func (a *OnePasswordConnect) GetSecrets(path string, version string, annotations return nil, err } - utils.VerboseToStdErr("OnePassword Connect get secret response: %v", result) + utils.VerboseToStdErr("OnePassword Connect get secret response: %v", utils.SanitizeUnsafe(result)) data := make(map[string]interface{}) diff --git a/pkg/backends/vault.go b/pkg/backends/vault.go index 8d90151e..a685e4d2 100644 --- a/pkg/backends/vault.go +++ b/pkg/backends/vault.go @@ -61,7 +61,7 @@ func (v *Vault) GetSecrets(path string, version string, annotations map[string]s return nil, err } - utils.VerboseToStdErr("Hashicorp Vault get kv pairs response: %v", secret) + utils.VerboseToStdErr("Hashicorp Vault get kv pairs response: %v", utils.SanitizeUnsafe(secret)) if secret == nil { // Do not mention `version` in error message when it's not honored (KV-V1) diff --git a/pkg/backends/yandexcloudlockbox.go b/pkg/backends/yandexcloudlockbox.go index 7e07091d..f0c74cb4 100644 --- a/pkg/backends/yandexcloudlockbox.go +++ b/pkg/backends/yandexcloudlockbox.go @@ -41,7 +41,7 @@ func (ycl *YandexCloudLockbox) GetSecrets(secretID string, version string, _ map return nil, err } - utils.VerboseToStdErr("Yandex Cloud Lockbox get secret response %v", resp) + utils.VerboseToStdErr("Yandex Cloud Lockbox get secret response %v", utils.SanitizeUnsafe(resp)) result := make(map[string]interface{}, len(resp.GetEntries())) for _, v := range resp.GetEntries() { diff --git a/pkg/kube/util.go b/pkg/kube/util.go index aeaccc20..c6bf707d 100644 --- a/pkg/kube/util.go +++ b/pkg/kube/util.go @@ -210,7 +210,7 @@ func configReplacement(key, value string, resource Resource) (interface{}, []err // configMap data values must be strings - utils.VerboseToStdErr("key %s comes from ConfigMap manifest, stringifying value %s to fit", key, value) + utils.VerboseToStdErr("key %s comes from ConfigMap manifest, stringifying value %s to fit", key, utils.SanitizeUnsafe(value)) return stringify(res), err } @@ -219,7 +219,7 @@ func secretReplacement(key, value string, resource Resource) (interface{}, []err if err == nil && genericPlaceholder.Match(decoded) { res, err := genericReplacement(key, string(decoded), resource) - utils.VerboseToStdErr("key %s comes from Secret manifest, base64 encoding value %s to fit", key, value) + utils.VerboseToStdErr("key %s comes from Secret manifest, base64 encoding value %s to fit", key, utils.SanitizeUnsafe(value)) return base64.StdEncoding.EncodeToString([]byte(stringify(res))), err }