Skip to content

Commit

Permalink
Merge e2b4b1c into 86c6049
Browse files Browse the repository at this point in the history
  • Loading branch information
wallyqs committed Oct 4, 2018
2 parents 86c6049 + e2b4b1c commit 138f2bd
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 32 deletions.
34 changes: 18 additions & 16 deletions server/client.go
Expand Up @@ -21,7 +21,6 @@ import (
"io"
"math/rand"
"net"
"regexp"
"strings"
"sync"
"sync/atomic"
Expand Down Expand Up @@ -754,29 +753,32 @@ func (c *client) processErr(errStr string) {
c.closeConnection(ParseError)
}

// Password pattern matcher.
var passPat = regexp.MustCompile(`"?\s*pass\S*?"?[:=]\s*"?(([^"])*)`)

// This will remove any notion of passwords from trace messages
// for logging.
// removePassFromTrace removes any notion of passwords from trace
// messages for logging.
func removePassFromTrace(arg []byte) []byte {

if !bytes.Contains(arg, []byte("pass")) {
return arg
}
m := passPat.FindAllSubmatch(arg, -1)
if len(m) == 0 {
m := map[string]interface{}{}
err := json.Unmarshal(arg, &m)
if err != nil {
// Leave as is to be able to trace malformed connect
// messages.
return arg
}

for _, match := range m {
if len(match) != 3 {
continue
}
arg = bytes.Replace(arg, match[1], []byte("[REDACTED]"), 1)

redactedPass := "[REDACTED]"
if _, ok := m["password"]; ok {
m["password"] = redactedPass
}
if _, ok := m["pass"]; ok {
m["pass"] = redactedPass
}
result, err := json.Marshal(m)
if err != nil {
return arg
}
return arg
return result
}

func (c *client) processConnect(arg []byte) error {
Expand Down
124 changes: 108 additions & 16 deletions server/log_test.go
Expand Up @@ -218,20 +218,112 @@ func TestNoPasswordsFromConnectTrace(t *testing.T) {
}

func TestRemovePassFromTrace(t *testing.T) {
pass := []byte("s3cr3t")
check := func(r []byte) {
t.Helper()
if bytes.Contains(r, pass) {
t.Fatalf("Found password in %q", r)
}
}
check(removePassFromTrace([]byte("CONNECT {\"user\":\"derek\",\"pass\":\"s3cr3t\"}\r\n")))
check(removePassFromTrace([]byte("CONNECT {\"user\":\"derek\",\"pass\": \"s3cr3t\"}\r\n")))
check(removePassFromTrace([]byte("CONNECT {\"user\":\"derek\",\"pass\": \"s3cr3t\" }\r\n")))
check(removePassFromTrace([]byte("CONNECT {\"pass\":\"s3cr3t\",}\r\n")))
check(removePassFromTrace([]byte("CONNECT {pass:s3cr3t , password = s3cr3t}")))
check(removePassFromTrace([]byte("CONNECT {\"echo\":true,\"verbose\":false,\"pedantic\":false,\"user\":\"foo\",\"pass\":\"s3cr3t\",\"tls_required\":false,\"name\":\"APM7JU94z77YzP6WTBEiuw\"}\r\n")))
check(removePassFromTrace([]byte("CONNECT {pass:s3cr3t\r\n")))
check(removePassFromTrace([]byte("CONNECT {\"password\":\"s3cr3t\",}\r\n")))
check(removePassFromTrace([]byte("CONNECT {\"echo\":true,\"verbose\":false,\"pedantic\":false,\"user\":\"foo\",\"password\":\"s3cr3t\",\"tls_required\":false,\"name\":\"APM7JU94z77YzP6WTBEiuw\"}\r\n")))
tests := []struct {
name string
input string
expected string
}{
{
"user and pass",
`{"user":"derek","pass":"s3cr3t"}`,
`{"pass":"[REDACTED]","user":"derek"}`,
},
{
"user and pass",
"{\"user\":\"derek\",\"pass\": \"s3cr3t\" }",
"{\"pass\":\"[REDACTED]\",\"user\":\"derek\"}",
},
{
"user and password",
`{"user":"derek","password": "s3cr3t"}`,
`{"password":"[REDACTED]","user":"derek"}`,
},
{
"only pass",
"{\"pass\":\"s3cr3t\"}",
"{\"pass\":\"[REDACTED]\"}",
},
{
"only password",
"{\"password\":\"s3cr3t\"}",
"{\"password\":\"[REDACTED]\"}",
},
{
"pass and password",
`{"pass":"s3cr3t","password":"s3cr3t"}`,
`{"pass":"[REDACTED]","password":"[REDACTED]"}`,
},
{
"long password",
"{\"pass\":\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"}",
"{\"pass\":\"[REDACTED]\"}",
},
{
"multiple passwords",
"{\"pass\":\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\",\"pass\":\"BBBBBBBBBBBBBBBBBBBB\",\"password\":\"CCCCCCCCCCCCCCCC\"}",
"{\"pass\":\"[REDACTED]\",\"password\":\"[REDACTED]\"}",
},
// NOTE: In the result the keys are changed to be in alphabetical order
{
"full connect example",
"{\"echo\":true,\"verbose\":false,\"pedantic\":false,\"user\":\"foo\",\"pass\":\"s3cr3t\",\"tls_required\":false,\"name\":\"APM7JU94z77YzP6WTBEiuw\"}",
"{\"echo\":true,\"name\":\"APM7JU94z77YzP6WTBEiuw\",\"pass\":\"[REDACTED]\",\"pedantic\":false,\"tls_required\":false,\"user\":\"foo\",\"verbose\":false}",
},
{
"full connect sample",
"{\"echo\":true,\"verbose\":false,\"pedantic\":false,\"user\":\"foo\",\"password\":\"s3cr3t\",\"tls_required\":false,\"name\":\"APM7JU94z77YzP6WTBEiuw\"}",
"{\"echo\":true,\"name\":\"APM7JU94z77YzP6WTBEiuw\",\"password\":\"[REDACTED]\",\"pedantic\":false,\"tls_required\":false,\"user\":\"foo\",\"verbose\":false}",
},
{
"user and password are the same",
"{\"echo\":true,\"verbose\":false,\"pedantic\":false,\"user\":\"s3cr3t\",\"password\":\"s3cr3t\",\"tls_required\":false,\"name\":\"...\"}",
"{\"echo\":true,\"name\":\"...\",\"password\":\"[REDACTED]\",\"pedantic\":false,\"tls_required\":false,\"user\":\"s3cr3t\",\"verbose\":false}",
},
{
"user, name and password are the same",
"{\"echo\":true,\"verbose\":false,\"pedantic\":false,\"user\":\"s3cr3t\",\"pass\":\"s3cr3t\",\"tls_required\":false,\"name\":\"s3cr3t\"}\r\n",
"{\"echo\":true,\"name\":\"s3cr3t\",\"pass\":\"[REDACTED]\",\"pedantic\":false,\"tls_required\":false,\"user\":\"s3cr3t\",\"verbose\":false}",
},
// No password leaves the connect message as is so keys are not sorted
{
"full connect example",
"{\"echo\":true,\"verbose\":false,\"pedantic\":false,\"user\":\"foo\",\"tls_required\":false,\"name\":\"APM7JU94z77YzP6WTBEiuw\"}",
"{\"echo\":true,\"verbose\":false,\"pedantic\":false,\"user\":\"foo\",\"tls_required\":false,\"name\":\"APM7JU94z77YzP6WTBEiuw\"}",
},
// If JSON payload is invalid then traced the message as is
{
"invalid JSON",
"{pass:s3cr3t , password= s3cr3t}\r\n",
"{pass:s3cr3t , password= s3cr3t}\r\n",
},
{
"invalid JSON",
"{user = hello, password = s3cr3t}",
"{user = hello, password = s3cr3t}",
},
{
"invalid JSON",
"{pass:s3cr3t\r\n",
"{pass:s3cr3t\r\n",
},
{
"invalid JSON",
"{\"password\":\"s3cr3t\",}\r\n",
"{\"password\":\"s3cr3t\",}\r\n",
},
{
"invalid JSON",
"{pass: \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\",pass= \"BBBBBBBBBBBBBBBBBBBB\",password =\"CCCCCCCCCCCCCCCC\"}\r\n",
"{pass: \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\",pass= \"BBBBBBBBBBBBBBBBBBBB\",password =\"CCCCCCCCCCCCCCCC\"}\r\n",
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
output := removePassFromTrace([]byte(test.input))
if !bytes.Equal(output, []byte(test.expected)) {
t.Errorf("\nExpected %q\n got: %q", test.expected, string(output))
}
})
}
}

0 comments on commit 138f2bd

Please sign in to comment.