diff --git a/internal/authprovider/ldap.go b/internal/authprovider/ldap.go index bc52c704..e65d086e 100644 --- a/internal/authprovider/ldap.go +++ b/internal/authprovider/ldap.go @@ -3,6 +3,7 @@ package ldap import ( "crypto/tls" "fmt" + "regexp" "github.com/ca-gip/kubi/internal/utils" "github.com/pkg/errors" @@ -330,7 +331,8 @@ func HasOpsAccess(userDN string) bool { // request to search user func newUserSearchRequest(userBaseDN string, username string) *ldap.SearchRequest { - userFilter := fmt.Sprintf(utils.Config.Ldap.UserFilter, username) + escapeFilter := regexp.MustCompile(`[(|)|\||&|*]`) + userFilter := fmt.Sprintf(utils.Config.Ldap.UserFilter, escapeFilter.ReplaceAllString(username, "")) return &ldap.SearchRequest{ BaseDN: userBaseDN, Scope: ldap.ScopeWholeSubtree, diff --git a/internal/authprovider/ldap_test.go b/internal/authprovider/ldap_test.go new file mode 100644 index 00000000..36435dd1 --- /dev/null +++ b/internal/authprovider/ldap_test.go @@ -0,0 +1,44 @@ +package ldap + +import ( + "strings" + "testing" + + "github.com/ca-gip/kubi/internal/utils" + "github.com/ca-gip/kubi/pkg/types" + "github.com/stretchr/testify/assert" +) + +func TestNewUserSearchRequest(t *testing.T) { + t.Run("escape out special character from username input", func(t *testing.T) { + utils.Config = &types.Config{ + Ldap: types.LdapConfig{ + UserFilter: "(cn=%s)", + }, + } + username := `)foo()*|&bar` + + expected := `(cn=foobar)` + + req := newUserSearchRequest("baseDN", username) + assert.Equal(t, expected, req.Filter) + }) +} + +func FuzzNewUserSearchRequest(f *testing.F) { + utils.Config = &types.Config{ + Ldap: types.LdapConfig{ + UserFilter: "%s", + }, + } + specials := []string{"(", ")", "&", "*", "|"} + + for _, s := range specials { + f.Add(s) + } + + f.Fuzz(func(t *testing.T, s string) { + req := newUserSearchRequest("baseDN", s) + assert.False(t, strings.ContainsAny(req.Filter, "()*&|")) + }) +}