From 1d98b690be2e5b7dd7ac4e56826615b3ca5d088f Mon Sep 17 00:00:00 2001 From: Nathan LeClaire Date: Fri, 11 Dec 2015 16:56:19 -0800 Subject: [PATCH] Strip certs and keys in log before sending to Bugsnag Signed-off-by: Nathan LeClaire --- libmachine/log/log.go | 27 +++++++++-- libmachine/log/log_test.go | 91 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 libmachine/log/log_test.go diff --git a/libmachine/log/log.go b/libmachine/log/log.go index eff2b11d4b..90fef58778 100644 --- a/libmachine/log/log.go +++ b/libmachine/log/log.go @@ -1,13 +1,34 @@ package log -import "io" +import ( + "io" + "regexp" +) -var Logger MachineLogger +const redactedText = "" + +var ( + Logger MachineLogger + + // (?s) enables '.' to match '\n' -- see https://golang.org/pkg/regexp/syntax/ + certRegex = regexp.MustCompile("(?s)-----BEGIN CERTIFICATE-----.*-----END CERTIFICATE-----") + keyRegex = regexp.MustCompile("(?s)-----BEGIN RSA PRIVATE KEY-----.*-----END RSA PRIVATE KEY-----") +) func init() { Logger = NewFmtMachineLogger() } +func stripSecrets(original []string) []string { + stripped := []string{} + for _, line := range original { + line = certRegex.ReplaceAllString(line, redactedText) + line = keyRegex.ReplaceAllString(line, redactedText) + stripped = append(stripped, line) + } + return stripped +} + // RedirectStdOutToStdErr prevents any log from corrupting the output func RedirectStdOutToStdErr() { Logger.RedirectStdOutToStdErr() @@ -62,5 +83,5 @@ func SetOutput(out io.Writer) { } func History() []string { - return Logger.History() + return stripSecrets(Logger.History()) } diff --git a/libmachine/log/log_test.go b/libmachine/log/log_test.go new file mode 100644 index 0000000000..2343ab98ff --- /dev/null +++ b/libmachine/log/log_test.go @@ -0,0 +1,91 @@ +package log + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestStripSecrets(t *testing.T) { + testCases := []struct { + description string + input []string + expected []string + }{ + { + description: "Log that does contain certs should have them stripped", + input: []string{ + "Some mundane log lines", + "IP is foo.bar", + `Secret here: printf '%s' '-----BEGIN CERTIFICATE----- +MIIC4DCCAcigAwIBAgIRAMMHbb4WFRVYsCOIrfM3dqkwDQYJKoZIhvcNAQELBQAw +GTEXMBUGA1UEChMObmF0aGFubGVjbGFpcmUwHhcNMTUxMDEwMDE1MDAwWhcNMTgw +OTI0MDE1MDAwWjAZMRcwFQYDVQQKEw5uYXRoYW5sZWNsYWlyZTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANLMyaAZPThE6lXtXYfUMZeF0pEfO4BQ7Rv8 +Q9/aIKwm8SlKNm+g+6+RoexsiaPXmAkqk04kg+f9WRgtUKC3nhaiUwTqx2HtxowY +Kp7VVW9QyzwCP1r04WTNTdICzhwM5GfaCMKLmibVUfh9GqIYg4Z6eFly7t0PaN1P +uaLClow1e4sWgAgkpIx7ko9ZtW+73knAnp9PPoH4KPBLS+sIPNGh62WsDlvQrOnq +KDiBPIAAMxu2UefIPeGe6xxFuCG89RoJYYsB627IaR8R8iGJMwjJsiAiObGu6z8M +lcWxT4dC+cEIDRu+XQmavJlAydBeHY6/gtJXzsyRExHTyDwi8xkCAwEAAaMjMCEw +DgYDVR0PAQH/BAQDAgKsMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQAD +ggEBAA5CBXPgjvxfY5bR+f6YfcDcKBWxOQ5zN+OH6jWpVzJMEUWp/ZvTQ1GcV1CT +J4HDMRUOL6lQigZDKR6OJ0g/pD4cDGEQlCuPDXx0O8eenxj9TQ+X+qdtxQNkgjId +QWj3k3JDHCh4BQ7h1ZJIg4SnGCUsrQQ+M8TS4Z0YZ/bZ6ZTktJgQgWMn9Uum1GN9 +hXJ/fa/E9OJuRxTXou7J0WwrV9aX9sEM9syOANR88PcA1fSE7+wNSdj5ZCfY6mQn +II9e8NZEf5ktPXCNi0LKI6R1berejwQI3KKHEFbdZ8SKn93HgDh/Ip/dFctj+zBt +CAlTWS3abehlCERn6Ze9IfZBtpI= +-----END CERTIFICATE-----' | sudo tee /etc/docker/ca.pem`, + }, + expected: []string{ + "Some mundane log lines", + "IP is foo.bar", + `Secret here: printf '%s' '' | sudo tee /etc/docker/ca.pem`, + }, + }, + { + description: "Log that does contain private keys should have them stripped", + input: []string{ + "Some mundane log lines", + "IP is foo.bar", + `Secret here: printf '%s' '-----BEGIN RSA PRIVATE KEY----- +MIIC4DCCAcigAwIBAgIRAMMHbb4WFRVYsCOIrfM3dqkwDQYJKoZIhvcNAQELBQAw +GTEXMBUGA1UEChMObmF0aGFubGVjbGFpcmUwHhcNMTUxMDEwMDE1MDAwWhcNMTgw +OTI0MDE1MDAwWjAZMRcwFQYDVQQKEw5uYXRoYW5sZWNsYWlyZTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANLMyaAZPThE6lXtXYfUMZeF0pEfO4BQ7Rv8 +Q9/aIKwm8SlKNm+g+6+RoexsiaPXmAkqk04kg+f9WRgtUKC3nhaiUwTqx2HtxowY +Kp7VVW9QyzwCP1r04WTNTdICzhwM5GfaCMKLmibVUfh9GqIYg4Z6eFly7t0PaN1P +uaLClow1e4sWgAgkpIx7ko9ZtW+73knAnp9PPoH4KPBLS+sIPNGh62WsDlvQrOnq +KDiBPIAAMxu2UefIPeGe6xxFuCG89RoJYYsB627IaR8R8iGJMwjJsiAiObGu6z8M +lcWxT4dC+cEIDRu+XQmavJlAydBeHY6/gtJXzsyRExHTyDwi8xkCAwEAAaMjMCEw +DgYDVR0PAQH/BAQDAgKsMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQAD +ggEBAA5CBXPgjvxfY5bR+f6YfcDcKBWxOQ5zN+OH6jWpVzJMEUWp/ZvTQ1GcV1CT +J4HDMRUOL6lQigZDKR6OJ0g/pD4cDGEQlCuPDXx0O8eenxj9TQ+X+qdtxQNkgjId +QWj3k3JDHCh4BQ7h1ZJIg4SnGCUsrQQ+M8TS4Z0YZ/bZ6ZTktJgQgWMn9Uum1GN9 +hXJ/fa/E9OJuRxTXou7J0WwrV9aX9sEM9syOANR88PcA1fSE7+wNSdj5ZCfY6mQn +II9e8NZEf5ktPXCNi0LKI6R1berejwQI3KKHEFbdZ8SKn93HgDh/Ip/dFctj+zBt +CAlTWS3abehlCERn6Ze9IfZBtpI= +-----END RSA PRIVATE KEY-----' | sudo tee /etc/docker/server-key.pem`, + }, + expected: []string{ + "Some mundane log lines", + "IP is foo.bar", + `Secret here: printf '%s' '' | sudo tee /etc/docker/server-key.pem`, + }, + }, + { + description: "Log that does not contain secrets should not change", + input: []string{ + "Some mundane log lines", + "IP is foo.bar", + }, + expected: []string{ + "Some mundane log lines", + "IP is foo.bar", + }, + }, + } + + for _, tc := range testCases { + assert.Equal(t, tc.expected, stripSecrets(tc.input)) + } +}