59 lines
1.9 KiB
Plaintext
59 lines
1.9 KiB
Plaintext
== How to fix it in Symfony
|
|
|
|
=== 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,php,diff-id=1,diff-type=noncompliant]
|
|
----
|
|
use Symfony\Component\Ldap\Ldap;
|
|
use Symfony\Component\Ldap\LdapInterface;
|
|
|
|
private function userLookup(Ldap $conn, Request $request)
|
|
{
|
|
$user = $request->query->get('user');
|
|
|
|
$conn->bind("cn=example,dc=example,dc=org", "example");
|
|
|
|
$query = $conn->query('dc=example,dc=org', '(&(objectclass=user)(uid=' . $user . '))'); // Noncompliant
|
|
$query->execute();
|
|
}
|
|
----
|
|
|
|
==== Compliant solution
|
|
|
|
[source,php,diff-id=1,diff-type=compliant]
|
|
----
|
|
use Symfony\Component\Ldap\Ldap;
|
|
use Symfony\Component\Ldap\LdapInterface;
|
|
|
|
private function userLookup(Ldap $conn, Request $request)
|
|
{
|
|
$user = $conn->escape($request->query->get('user'),'', LdapInterface::ESCAPE_FILTER);
|
|
|
|
$conn->bind("cn=example,dc=example,dc=org", "example");
|
|
|
|
$query = $conn->query('dc=example,dc=org', '(&(objectclass=user)(uid=' . $user . '))');
|
|
$query->execute();
|
|
}
|
|
----
|
|
|
|
=== How does this work?
|
|
|
|
include::../../common/fix/validation.adoc[]
|
|
|
|
For Symfony, the LDAP component method
|
|
https://github.com/symfony/symfony/blob/6.2/src/Symfony/Component/Ldap/LdapInterface.php#L45[`escape`] allows sanitizing these characters.
|
|
|
|
In the compliant solution example, the
|
|
`Ldap::escape` method is used with the `ESCAPE_FILTER` flag, which sanitizes potentially malicious characters in the search filter. The function can also be used with the
|
|
`ESCAPE_DN` flag, which sanitizes the distinguished name (DN).
|
|
|
|
Symfony also provides an
|
|
ad-hoc alternative for user lookup called
|
|
https://symfony.com/doc/current/security/ldap.html#security-ldap-user-provider[`LDAP User Provider`]. As opposed to the LDAP component, the LDAP User Provider
|
|
handles already user input sanitization.
|