Files
codeql/go/ql/test/experimental/CWE-090/LDAPInjection.go
2022-05-20 10:07:19 -07:00

136 lines
4.8 KiB
Go

package main
//go:generate depstubber -vendor github.com/go-ldap/ldap "" ScopeWholeSubtree,NeverDerefAliases,NewSearchRequest,EscapeFilter
//go:generate depstubber -vendor github.com/go-ldap/ldap/v3 "" ScopeWholeSubtree,NeverDerefAliases,NewSearchRequest,EscapeFilter
//go:generate depstubber -vendor github.com/jtblin/go-ldap-client LDAPClient
//go:generate depstubber -vendor gopkg.in/ldap.v2 "" ScopeWholeSubtree,NeverDerefAliases,NewSearchRequest,EscapeFilter
import (
"net/http"
"strings"
goldap "github.com/go-ldap/ldap"
goldapv3 "github.com/go-ldap/ldap/v3"
ldapclient "github.com/jtblin/go-ldap-client"
gopkgldapv2 "gopkg.in/ldap.v2"
)
type Ldap struct{}
func (*Ldap) sanitizedUserQuery(username string) (string, bool) {
badCharacters := "\x00()*\\"
if strings.ContainsAny(username, badCharacters) {
return "", false
}
return username, true
}
func (*Ldap) sanitizedUserDN(username string) (string, bool) {
badCharacters := "\x00()*\\"
if strings.ContainsAny(username, badCharacters) {
return "", false
}
return username, true
}
func (*Ldap) sanitizedGroupFilter(username string) (string, bool) {
badCharacters := "\x00()*\\"
if strings.ContainsAny(username, badCharacters) {
return "", false
}
return username, true
}
func (*Ldap) sanitizedGroupDN(username string) (string, bool) {
badCharacters := "\x00()*\\"
if strings.ContainsAny(username, badCharacters) {
return "", false
}
return username, true
}
func main() {}
// bad is an example of a bad implementation
func (ld *Ldap) bad(req *http.Request) {
// ...
untrusted := req.UserAgent()
goldap.NewSearchRequest(
untrusted, // BAD: untrusted dn
goldap.ScopeWholeSubtree, goldap.NeverDerefAliases, 0, 0, false,
"(&(objectClass=organizationalPerson))"+untrusted, // BAD: untrusted filter
[]string{"dn", "cn", untrusted}, // BAD: untrusted attribute
nil,
)
goldapv3.NewSearchRequest(
untrusted, // BAD: untrusted dn
goldap.ScopeWholeSubtree, goldap.NeverDerefAliases, 0, 0, false,
"(&(objectClass=organizationalPerson))"+untrusted, // BAD: untrusted filter
[]string{"dn", "cn", untrusted}, // BAD: untrusted attribute
nil,
)
gopkgldapv2.NewSearchRequest(
untrusted, // BAD: untrusted dn
goldap.ScopeWholeSubtree, goldap.NeverDerefAliases, 0, 0, false,
"(&(objectClass=organizationalPerson))"+untrusted, // BAD: untrusted filter
[]string{"dn", "cn", untrusted}, // BAD: untrusted attribute
nil,
)
client := &ldapclient.LDAPClient{}
client.Authenticate(untrusted, "123456") // BAD: untrusted filter
client.GetGroupsOfUser(untrusted) // BAD: untrusted filter
// ...
}
// good is an example of a good implementation
func (ld *Ldap) good(req *http.Request) {
// ...
untrusted := req.UserAgent()
escapegoldap := goldap.EscapeFilter(untrusted)
goldap.NewSearchRequest(
escapegoldap, // GOOD: sanitized dn
goldap.ScopeWholeSubtree, goldap.NeverDerefAliases, 0, 0, false,
"(&(objectClass=organizationalPerson))"+escapegoldap, // GOOD: sanitized filter
[]string{"dn", "cn", escapegoldap}, // GOOD: sanitized attribute
nil,
)
escapegoldapv3 := goldapv3.EscapeFilter(untrusted)
goldapv3.NewSearchRequest(
escapegoldapv3, // GOOD: sanitized dn
goldap.ScopeWholeSubtree, goldap.NeverDerefAliases, 0, 0, false,
"(&(objectClass=organizationalPerson))"+escapegoldapv3, // GOOD: sanitized filter
[]string{"dn", "cn", escapegoldapv3}, // GOOD: sanitized attribute
nil,
)
escapegopkgv2 := gopkgldapv2.EscapeFilter(untrusted)
gopkgldapv2.NewSearchRequest(
escapegopkgv2, // GOOD: sanitized dn
goldap.ScopeWholeSubtree, goldap.NeverDerefAliases, 0, 0, false,
"(&(objectClass=organizationalPerson))"+escapegopkgv2, // GOOD: sanitized filter
[]string{"dn", "cn", escapegopkgv2}, // GOOD: sanitized attribute
nil,
)
escapedusercustom, _ := ld.sanitizedUserQuery(untrusted) // GOOD: custom sanitized filter
escapedgroupcustom, _ := ld.sanitizedGroupFilter(untrusted) // GOOD: custom sanitized filter
escapeduserdncustom, _ := ld.sanitizedUserDN(untrusted) // GOOD: custom sanitized filter
escapedgroupdncustom, _ := ld.sanitizedGroupDN(untrusted) // GOOD: custom sanitized filter
client := &ldapclient.LDAPClient{}
client.Authenticate(escapedusercustom, "123456") // GOOD: sanitized filter
client.GetGroupsOfUser(escapedgroupcustom) // GOOD: sanitized filter
gopkgldapv2.NewSearchRequest(
escapeduserdncustom, // GOOD: sanitized dn
goldap.ScopeWholeSubtree, goldap.NeverDerefAliases, 0, 0, false,
"(&(objectClass=organizationalPerson))"+"(uid=1)",
[]string{"dn", "cn"},
nil,
)
gopkgldapv2.NewSearchRequest(
escapedgroupdncustom, // GOOD: sanitized dn
goldap.ScopeWholeSubtree, goldap.NeverDerefAliases, 0, 0, false,
"(&(objectClass=organizationalPerson))"+"(uid=1)",
[]string{"dn", "cn"},
nil,
)
// ...
}