diff --git a/lib/backend/sanitize.go b/lib/backend/sanitize.go index 1e04723050a24..c36828b4ca0e4 100644 --- a/lib/backend/sanitize.go +++ b/lib/backend/sanitize.go @@ -34,11 +34,25 @@ const errorMessage = "special characters are not allowed in resource names, plea var allowPattern = regexp.MustCompile(`^[0-9A-Za-z@_:.\-/+]*$`) // denyPattern matches some unallowed combinations -var denyPattern = regexp.MustCompile(`//`) +var denyPatterns = []*regexp.Regexp{ + regexp.MustCompile(`//`), + regexp.MustCompile(`(^|/)\.\.?(/|$)`), +} // isKeySafe checks if the passed in key conforms to whitelist func isKeySafe(s []byte) bool { - return allowPattern.Match(s) && !denyPattern.Match(s) && utf8.Valid(s) + return allowPattern.Match(s) && !denyPatternsMatch(s) && utf8.Valid(s) +} + +// denyPatternsMatch checks if the passed in key conforms to the deny patterns. +func denyPatternsMatch(s []byte) bool { + for _, pattern := range denyPatterns { + if pattern.Match(s) { + return true + } + } + + return false } // Sanitizer wraps a Backend implementation to make sure all values requested diff --git a/lib/backend/sanitize_test.go b/lib/backend/sanitize_test.go index cd7ae6cd9ac54..dca2b696014be 100644 --- a/lib/backend/sanitize_test.go +++ b/lib/backend/sanitize_test.go @@ -37,6 +37,54 @@ func TestSanitize(t *testing.T) { inKey: []byte("/namespaces//params"), assert: require.Error, }, + { + inKey: []byte("/namespaces/.."), + assert: require.Error, + }, + { + inKey: []byte("/namespaces/../params"), + assert: require.Error, + }, + { + inKey: []byte("/namespaces/..params"), + assert: require.NoError, + }, + { + inKey: []byte("/namespaces/."), + assert: require.Error, + }, + { + inKey: []byte("/namespaces/./params"), + assert: require.Error, + }, + { + inKey: []byte("/namespaces/.params"), + assert: require.NoError, + }, + { + inKey: []byte(".."), + assert: require.Error, + }, + { + inKey: []byte("..params"), + assert: require.NoError, + }, + { + inKey: []byte("../params"), + assert: require.Error, + }, + { + inKey: []byte("."), + assert: require.Error, + }, + { + inKey: []byte(".params"), + assert: require.NoError, + }, + { + inKey: []byte("./params"), + assert: require.Error, + }, { inKey: RangeEnd([]byte("a-b/c:d/.e_f/01")), assert: require.NoError,