56 lines
1.6 KiB
Plaintext
56 lines
1.6 KiB
Plaintext
== How to fix it in python-ldap
|
|
|
|
=== Code examples
|
|
|
|
The following noncompliant code is vulnerable to LDAP injection because untrusted data is
|
|
concatenated to an LDAP query without prior sanitization or validation.
|
|
|
|
==== Noncompliant code example
|
|
|
|
[source,python,diff-id=1,diff-type=noncompliant]
|
|
----
|
|
from flask import request
|
|
import ldap
|
|
|
|
@app.route("/user")
|
|
def user():
|
|
username = request.args['username']
|
|
|
|
search_filter = "(&(objectClass=user)(uid="+username+"))"
|
|
|
|
ldap_connection = ldap.initialize("ldap://localhost:389")
|
|
user = ldap_connection.search_s("dc=example,dc=org", ldap.SCOPE_SUBTREE, search_filter) # Noncompliant
|
|
|
|
return user[0]
|
|
----
|
|
|
|
==== Compliant solution
|
|
|
|
[source,python,diff-id=1,diff-type=compliant]
|
|
----
|
|
from flask import request
|
|
import ldap
|
|
|
|
@app.route("/user")
|
|
def user():
|
|
username = ldap.filter.escape_filter_chars(request.args['username'])
|
|
|
|
search_filter = "(&(objectClass=user)(uid="+username+"))"
|
|
|
|
ldap_connection = ldap.initialize("ldap://localhost:389")
|
|
user = ldap_connection.search_s("dc=example,dc=org", ldap.SCOPE_SUBTREE, search_filter)
|
|
|
|
return user[0]
|
|
----
|
|
|
|
=== How does this work?
|
|
|
|
include::../../common/fix/validation.adoc[]
|
|
|
|
For Python, the python-ldap library functions
|
|
https://www.python-ldap.org/en/python-ldap-3.3.0/reference/ldap-filter.html[`escape_filter_chars`] and
|
|
https://www.python-ldap.org/en/python-ldap-3.3.0/reference/ldap-dn.html?highlight=escape_dn#ldap.dn.escape_dn_chars[`escape_dn_chars`] allow sanitizing these characters.
|
|
|
|
In the compliant solution example, the `escape_filter_chars`
|
|
is used to sanitize the search filter concatenated input.
|