== 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=11,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=11,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.
