简体   繁体   中英

Django LDAP3 security with TLS: am I secure?

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?

We use LDAP for authentication with our flagship Django website in our organization, using TLS certificates. It is unclear whether or not you are, as your destination URL seems to be ldap:// instead of ldaps:// . Typically, non-secure LDAP runs on port 389 while secure LDAPS runs on port 636 .

With that background out of the way, I would highly recommend using the django-python3-ldap package, which we have been using for several years, with over 200,000 users in LDAP using the objectClasses top, account, and posixAccount. You can find it here: https://github.com/etianen/django-python3-ldap

LDAP is a complex protocol, and there are a lot of places where one can go wrong writing a backend (trust me, I tried the path you are going down). The django-python3-ldap package is battle tested and will avoid these pitfalls. Your colleagues can probably assist you with the proper settings to get it working. Good luck!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM