|
31 | 31 | log = logger.create() |
32 | 32 |
|
33 | 33 |
|
| 34 | +def _escape_ldap_filter(s): |
| 35 | + """Escape special characters for safe use in LDAP filter strings (RFC 4515).""" |
| 36 | + s = s.replace('\\', '\\5c') |
| 37 | + s = s.replace('*', '\\2a') |
| 38 | + s = s.replace('(', '\\28') |
| 39 | + s = s.replace(')', '\\29') |
| 40 | + s = s.replace('\x00', '\\00') |
| 41 | + return s |
| 42 | + |
| 43 | + |
34 | 44 | class LDAPLogger(object): |
35 | 45 |
|
36 | 46 | @staticmethod |
@@ -148,9 +158,11 @@ def bind_user(username, password): |
148 | 158 |
|
149 | 159 | :returns: True if login succeeded, False if login failed, None if server unavailable. |
150 | 160 | ''' |
| 161 | + # Escape LDAP special characters to prevent LDAP injection in search filters |
| 162 | + safe_username = _escape_ldap_filter(username) |
151 | 163 | try: |
152 | | - if _ldap.get_object_details(username): |
153 | | - result = _ldap.bind_user(username, password) |
| 164 | + if _ldap.get_object_details(safe_username): |
| 165 | + result = _ldap.bind_user(safe_username, password) |
154 | 166 | log.debug("LDAP login '%s': %r", username, result) |
155 | 167 | return result is not None, None |
156 | 168 | return None, None # User not found |
|
0 commit comments