Use constant time string compare for match value

Fixes #364
This commit is contained in:
Cameron Moore 2019-12-10 22:21:30 -06:00
parent c47c06e822
commit 31e76bcd00
2 changed files with 21 additions and 1 deletions

View file

@ -6,6 +6,7 @@ import (
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"crypto/subtle"
"encoding/base64"
"encoding/hex"
"encoding/json"
@ -787,7 +788,7 @@ func (r MatchRule) Evaluate(headers, query, payload *map[string]interface{}, bod
if arg, ok := r.Parameter.Get(headers, query, payload); ok {
switch r.Type {
case MatchValue:
return arg == r.Value, nil
return compare(arg, r.Value), nil
case MatchRegex:
return regexp.MatchString(r.Regex, arg)
case MatchHashSHA1:
@ -804,6 +805,11 @@ func (r MatchRule) Evaluate(headers, query, payload *map[string]interface{}, bod
return false, nil
}
// compare is a helper function for constant time string comparisons.
func compare(a, b string) bool {
return subtle.ConstantTimeCompare([]byte(a), []byte(b)) == 1
}
// getenv provides a template function to retrieve OS environment variables.
func getenv(s string) string {
return os.Getenv(s)

View file

@ -628,3 +628,17 @@ func TestNotRule(t *testing.T) {
}
}
}
func TestCompare(t *testing.T) {
for _, tt := range []struct {
a, b string
ok bool
}{
{"abcd", "abcd", true},
{"zyxw", "abcd", false},
} {
if ok := compare(tt.a, tt.b); ok != tt.ok {
t.Errorf("compare failed for %q and %q: got %v\n", tt.a, tt.b, ok)
}
}
}