diff --git a/client/config/config.go b/client/config/config.go index 61678ed7ac5b..2323d9add548 100644 --- a/client/config/config.go +++ b/client/config/config.go @@ -21,6 +21,7 @@ import ( var ( // DefaultEnvBlacklist is the default set of environment variables that are // filtered when passing the environment variables of the host to a task. + // duplicated in command/agent/host, update that if this changes. DefaultEnvBlacklist = strings.Join([]string{ "CONSUL_TOKEN", "CONSUL_HTTP_TOKEN", diff --git a/command/agent/host/host.go b/command/agent/host/host.go index 60e43d86a4a0..1940a01d22c8 100644 --- a/command/agent/host/host.go +++ b/command/agent/host/host.go @@ -1,6 +1,7 @@ package host import ( + "io/ioutil" "os" "strings" ) @@ -60,36 +61,63 @@ func diskUsage(path string) (du DiskUsage, err error) { return du, nil } +var ( + envRedactSet = makeEnvRedactSet() +) + // environment returns the process environment in a map func environment() map[string]string { env := make(map[string]string) for _, e := range os.Environ() { s := strings.SplitN(e, "=", 2) - env[s[0]] = s[1] + k := s[0] + up := strings.ToUpper(k) + v := s[1] + + _, redact := envRedactSet[k] + if redact || + strings.Contains(up, "TOKEN") || + strings.Contains(up, "SECRET") { + v = "" + } + + env[k] = v } return env } -// slurp returns the file contents as a string, ignoring errors +// makeEnvRedactSet creates a set of well known environment variables that should be +// redacted in the output +func makeEnvRedactSet() map[string]struct{} { + // Duplicated from config.DefaultEnvBlacklist in order to avoid an import cycle + configDefault := []string{ + "CONSUL_TOKEN", + "CONSUL_HTTP_TOKEN", + "VAULT_TOKEN", + "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN", + "GOOGLE_APPLICATION_CREDENTIALS", + } + + set := make(map[string]struct{}) + for _, e := range configDefault { + set[e] = struct{}{} + } + + return set +} + +// slurp returns the file contents as a string, returning an error string func slurp(path string) string { - var sb strings.Builder - buf := make([]byte, 512) fh, err := os.Open(path) if err != nil { return err.Error() } - var l int - for { - l, err = fh.Read(buf) - if err != nil { - if l > 0 { - sb.Write(buf[0 : l-1]) - } - break - } - sb.Write(buf[0 : l-1]) + bs, err := ioutil.ReadAll(fh) + if err != nil { + return err.Error() } - return sb.String() + + return string(bs) } diff --git a/command/agent/host/host_test.go b/command/agent/host/host_test.go index 42a223244b53..12131fa87a41 100644 --- a/command/agent/host/host_test.go +++ b/command/agent/host/host_test.go @@ -1,6 +1,7 @@ package host import ( + "os" "testing" "github.com/stretchr/testify/require" @@ -17,6 +18,15 @@ func TestHostUtils(t *testing.T) { } func TestMakeHostData(t *testing.T) { + // setenv variables that should be redacted + prev := os.Getenv("VAULT_TOKEN") + os.Setenv("VAULT_TOKEN", "foo") + defer os.Setenv("VAULT_TOKEN", prev) + + os.Setenv("BOGUS_TOKEN", "foo") + os.Setenv("BOGUS_SECRET", "foo") + os.Setenv("ryanSECRETS", "foo") + host, err := MakeHostData() require.NoError(t, err) require.NotEmpty(t, host.OS) @@ -24,4 +34,9 @@ func TestMakeHostData(t *testing.T) { require.NotEmpty(t, host.ResolvConf) require.NotEmpty(t, host.Hosts) require.NotEmpty(t, host.Disk) + require.NotEmpty(t, host.Environment) + require.Equal(t, "", host.Environment["VAULT_TOKEN"]) + require.Equal(t, "", host.Environment["BOGUS_TOKEN"]) + require.Equal(t, "", host.Environment["BOGUS_SECRET"]) + require.Equal(t, "", host.Environment["ryanSECRETS"]) }