Sanitizing input to LDAP authentication module.

This commit is contained in:
Sergio Benitez 2015-10-26 18:08:59 -07:00
parent b9f5def5dc
commit 630ebbe6c2

View File

@ -9,6 +9,7 @@ package ldap
import ( import (
"crypto/tls" "crypto/tls"
"fmt" "fmt"
"strings"
"github.com/gogits/gogs/modules/ldap" "github.com/gogits/gogs/modules/ldap"
"github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/log"
@ -33,6 +34,28 @@ type Source struct {
Enabled bool // if this source is disabled Enabled bool // if this source is disabled
} }
func (ls *Source) sanitizedUserQuery(username string) (string, bool) {
// See http://tools.ietf.org/search/rfc4515
badCharacters := "\x00()*\\"
if strings.ContainsAny(username, badCharacters) {
log.Debug("'%s' contains invalid query characters. Aborting.", username)
return "", false
}
return fmt.Sprintf(ls.Filter, username), true
}
func (ls *Source) sanitizedUserDN(username string) (string, bool) {
// See http://tools.ietf.org/search/rfc4514: "special characters"
badCharacters := "\x00()*\\,='\"#+;<> "
if strings.ContainsAny(username, badCharacters) {
log.Debug("'%s' contains invalid DN characters. Aborting.", username)
return "", false
}
return fmt.Sprintf(ls.UserDN, username), true
}
func (ls *Source) FindUserDN(name string) (string, bool) { func (ls *Source) FindUserDN(name string) (string, bool) {
l, err := ldapDial(ls) l, err := ldapDial(ls)
if err != nil { if err != nil {
@ -55,7 +78,11 @@ func (ls *Source) FindUserDN(name string) (string, bool) {
} }
// A search for the user. // A search for the user.
userFilter := fmt.Sprintf(ls.Filter, name) userFilter, ok := ls.sanitizedUserQuery(name)
if !ok {
return "", false
}
log.Trace("Searching using filter %s", userFilter) log.Trace("Searching using filter %s", userFilter)
search := ldap.NewSearchRequest( search := ldap.NewSearchRequest(
ls.UserBase, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, ls.UserBase, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0,
@ -85,7 +112,12 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str
var userDN string var userDN string
if directBind { if directBind {
log.Trace("LDAP will bind directly via UserDN template: %s", ls.UserDN) log.Trace("LDAP will bind directly via UserDN template: %s", ls.UserDN)
userDN = fmt.Sprintf(ls.UserDN, name)
var ok bool
userDN, ok = ls.sanitizedUserDN(name)
if !ok {
return "", "", "", false, false
}
} else { } else {
log.Trace("LDAP will use BindDN.") log.Trace("LDAP will use BindDN.")
@ -112,7 +144,11 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str
} }
log.Trace("Bound successfully with userDN: %s", userDN) log.Trace("Bound successfully with userDN: %s", userDN)
userFilter := fmt.Sprintf(ls.Filter, name) userFilter, ok := ls.sanitizedUserQuery(name)
if !ok {
return "", "", "", false, false
}
search := ldap.NewSearchRequest( search := ldap.NewSearchRequest(
userDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, userFilter, userDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, userFilter,
[]string{ls.AttributeName, ls.AttributeSurname, ls.AttributeMail}, []string{ls.AttributeName, ls.AttributeSurname, ls.AttributeMail},