Sanitizing input to LDAP authentication module.
This commit is contained in:
		
							parent
							
								
									b9f5def5dc
								
							
						
					
					
						commit
						630ebbe6c2
					
				@ -9,6 +9,7 @@ package ldap
 | 
			
		||||
import (
 | 
			
		||||
	"crypto/tls"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/gogits/gogs/modules/ldap"
 | 
			
		||||
	"github.com/gogits/gogs/modules/log"
 | 
			
		||||
@ -33,6 +34,28 @@ type Source struct {
 | 
			
		||||
	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) {
 | 
			
		||||
	l, err := ldapDial(ls)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@ -55,7 +78,11 @@ func (ls *Source) FindUserDN(name string) (string, bool) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 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)
 | 
			
		||||
	search := ldap.NewSearchRequest(
 | 
			
		||||
		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
 | 
			
		||||
	if directBind {
 | 
			
		||||
		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 {
 | 
			
		||||
		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)
 | 
			
		||||
	userFilter := fmt.Sprintf(ls.Filter, name)
 | 
			
		||||
	userFilter, ok := ls.sanitizedUserQuery(name)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return "", "", "", false, false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	search := ldap.NewSearchRequest(
 | 
			
		||||
		userDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, userFilter,
 | 
			
		||||
		[]string{ls.AttributeName, ls.AttributeSurname, ls.AttributeMail},
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user