Skip to content

Commit 3f8d6e8

Browse files
committed
prevent ldap injection
1 parent 7a60b34 commit 3f8d6e8

1 file changed

Lines changed: 26 additions & 12 deletions

File tree

apps/ldap/utils.py

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
Connection,
2525
Server,
2626
)
27+
from ldap3.utils.conv import escape_filter_chars
28+
from ldap3.utils.dn import escape_rdn
2729

2830
LDAP_SERVER_URL = "ldaps://ldap.csua.berkeley.edu"
2931
# TODO: make things faster because connect_timeout=2 was too slow (caused socket closure)
@@ -75,11 +77,12 @@ def make_password(password):
7577

7678

7779
def change_password(username, new_password):
80+
sanitized_username = escape_rdn(username)
7881
# using newuser_connection for edit privileges
7982
with newuser_connection() as c:
8083
if c.bind():
8184
success = c.modify(
82-
"uid={0},{1}".format(username, PEOPLE_OU),
85+
"uid={0},{1}".format(sanitized_username, PEOPLE_OU),
8386
{"userpassword": [MODIFY_REPLACE, make_password(new_password)]},
8487
)
8588
return success
@@ -95,9 +98,10 @@ def create_new_user(username, name, email, sid, password):
9598
9699
If uid is -1, this means the bind failed.
97100
"""
101+
sanitized_username = escape_rdn(username)
98102
with newuser_connection() as c:
99103
if c.bind():
100-
dn = "uid={0},{1}".format(username, PEOPLE_OU)
104+
dn = "uid={0},{1}".format(sanitized_username, PEOPLE_OU)
101105
uid = get_max_uid() + 1
102106
attrs = {
103107
"uid": username,
@@ -123,9 +127,10 @@ def delete_user(username):
123127
"""Deletes a user. Returns True on successful deletion, False on failed
124128
deletion, and raises a RuntimeError if newuser fails to bind.
125129
"""
130+
sanitized_username = escape_rdn(username)
126131
with newuser_connection() as c:
127132
if c.bind():
128-
dn = f"uid={username},{PEOPLE_OU}"
133+
dn = f"uid={sanitized_username},{PEOPLE_OU}"
129134
success = c.delete(dn)
130135
return success
131136
else:
@@ -173,7 +178,8 @@ def authenticate(username, password):
173178
"""
174179
verifies that the username and password are correct
175180
"""
176-
user_dn = "uid={0},{1}".format(username, PEOPLE_OU)
181+
sanitized_username = escape_rdn(username)
182+
user_dn = "uid={0},{1}".format(sanitized_username, PEOPLE_OU)
177183
with ldap_connection(user=user_dn, password=password) as c:
178184
if c.bind():
179185
return True
@@ -189,7 +195,8 @@ def get_all_groups():
189195

190196

191197
def get_group_members(group):
192-
search_filter = "(cn={0})".format(group)
198+
sanitized_group = escape_filter_chars(group)
199+
search_filter = "(cn={0})".format(sanitized_group)
193200
with ldap_connection() as c:
194201
c.search(GROUP_OU, search_filter, attributes=ALL_ATTRIBUTES)
195202
if len(c.entries) == 0:
@@ -217,11 +224,12 @@ def get_politburo():
217224

218225

219226
def get_user_creation_time(username):
227+
sanitized_username = escape_filter_chars(username)
220228
# WIP
221229
with ldap_connection() as c:
222230
c.search(
223231
PEOPLE_OU,
224-
"(uid={0})".format(username),
232+
"(uid={0})".format(sanitized_username),
225233
attributes=[
226234
"createTimestamp",
227235
"creatorsName",
@@ -241,35 +249,39 @@ def get_user_creation_time(username):
241249

242250

243251
def get_user_info(username):
252+
sanitized_username = escape_filter_chars(username)
244253
with ldap_connection() as c:
245-
c.search(PEOPLE_OU, "(uid={0})".format(username), attributes="*")
254+
c.search(PEOPLE_OU, "(uid={0})".format(sanitized_username), attributes="*")
246255
if len(c.entries) == 0:
247256
raise Http404("No such user!")
248257

249258
return c.entries[0]
250259

251260

252261
def get_user_gecos(username):
262+
sanitized_username = escape_filter_chars(username)
253263
with ldap_connection() as c:
254-
c.search(PEOPLE_OU, "(uid={0})".format(username), attributes="gecos")
264+
c.search(PEOPLE_OU, "(uid={0})".format(sanitized_username), attributes="gecos")
255265
if len(c.entries) == 0:
256266
raise Http404("No such user!")
257267

258268
return str(c.entries[0].gecos)
259269

260270

261271
def get_user_hashed_password(username):
272+
sanitized_username = escape_filter_chars(username)
262273
with newuser_connection() as c:
263-
c.search(PEOPLE_OU, "(uid={0})".format(username), attributes="userpassword")
274+
c.search(PEOPLE_OU, "(uid={0})".format(sanitized_username), attributes="userpassword")
264275
if len(c.entries) == 0:
265276
raise Http404("No such user!")
266277

267278
return str(c.entries[0].userpassword)
268279

269280

270281
def user_exists(username):
282+
sanitized_username = escape_filter_chars(username)
271283
with ldap_connection() as c:
272-
c.search(PEOPLE_OU, "(uid={0})".format(username), attributes="")
284+
c.search(PEOPLE_OU, "(uid={0})".format(sanitized_username), attributes="")
273285
return len(c.entries) == 1
274286

275287

@@ -289,17 +301,19 @@ def get_user_email(username):
289301

290302

291303
def email_exists(email):
304+
sanitized_email = escape_filter_chars(email)
292305
with ldap_connection() as c:
293-
search_filter = "(gecos=*{0})".format(email)
306+
search_filter = "(gecos=*{0})".format(sanitized_email)
294307
c.search(PEOPLE_OU, search_filter, attributes="gecos")
295308
if len(c.entries) > 0:
296309
return True
297310
return False
298311

299312

300313
def get_user_groups(username):
314+
sanitized_username = escape_filter_chars(username)
301315
with ldap_connection() as c:
302-
c.search(GROUP_OU, "(memberUid={})".format(username), attributes="cn")
316+
c.search(GROUP_OU, "(memberUid={})".format(sanitized_username), attributes="cn")
303317
groups = [str(entry.cn) for entry in c.entries]
304318
return groups
305319

0 commit comments

Comments
 (0)