I'm concerned the login with LDAP in my Django app is not secure. After trying several methods, I was able to get a working custom backend using ldap3. I was advised by other programmers (unfortunately non-Django programmers) in my organization to use TLS, but when I make a connection with ldap3, it looks like it's not using TLS. I'm new to LDAP and security, but I've tried to do as much reading as possible, so hopefully I'm not missing something obvious.
Based on the ldap3 documentation, and trial-and-error, it seems that the connection has to be bound (conn.bind()
) before TLS can be started (conn.start_tls()
). Is this true? If the connection is bound without TLS, is this exposing a vulnerability? If so, what's the point of start TLS after the connection?
Am I using ldap3 and TLS correctly? Is this login method insecure, exposing passwords?
#backends.py
import ldap3
import ssl
class LDAPBackend(ModelBackend):
def authenticate(self, request, username=None, password=None):
server = ldap3.Server('ldap://<url>', use_ssl=True)
conn = ldap3.Connection(server, user=request.POST.get('username'), password=request.POST.get('password'))
try:
conn.bind()
conn.start_tls()
search_filter = '(&(objectClass=user)(userPrincipalName='+request.POST.get('username')+'))'
conn.search(search_base='<search terms>', search_filter=search_filter, search_scope='SUBTREE', attributes='*')
attrs = conn.response[0]['attributes']
username = attrs['userPrincipalName']
except:
return None
If I switch the conn.bind()
and conn.start_tls()
order (so TLS starts first), the login fails (the form says "Enter a correct username...").
Is it secure to have a login this way in a Django app?