Severity: High
Category
Concurrency / Insecure Design (OWASP A04)
Files
pkg/clients/ldap/client.go:72-91
Description
getConn() checks IsClosing() and replaces l.conn without any synchronization. Two goroutines calling getConn() at the same time when the connection is closing will both try to reconnect. One connection gets leaked and the write to l.conn at line 87 is a data race.
func (l *LDAPConn) getConn() LDAPConnClient {
if l.conn != nil && l.conn.IsClosing() {
newConn, err := ldap.DialURL(...)
// ...
l.conn = newConn // unsynchronized write
}
return l.conn
}
This gets called from multiple goroutines: reconciler, offboarding job, LDAP query resolution.
Fix
type LDAPConn struct {
mu sync.Mutex
conn LDAPConnClient
// ...
}
func (l *LDAPConn) getConn() LDAPConnClient {
l.mu.Lock()
defer l.mu.Unlock()
if l.conn != nil && l.conn.IsClosing() {
// reconnect
}
return l.conn
}
Severity: High
Category
Concurrency / Insecure Design (OWASP A04)
Files
pkg/clients/ldap/client.go:72-91Description
getConn()checksIsClosing()and replacesl.connwithout any synchronization. Two goroutines callinggetConn()at the same time when the connection is closing will both try to reconnect. One connection gets leaked and the write tol.connat line 87 is a data race.This gets called from multiple goroutines: reconciler, offboarding job, LDAP query resolution.
Fix