diff --git a/config.xsd b/config.xsd
index 18af17b88..4d22e413f 100644
--- a/config.xsd
+++ b/config.xsd
@@ -380,6 +380,7 @@
+
diff --git a/dictionaries/InternalTaintSinkMap.php b/dictionaries/InternalTaintSinkMap.php
index a792a6155..3908ff725 100644
--- a/dictionaries/InternalTaintSinkMap.php
+++ b/dictionaries/InternalTaintSinkMap.php
@@ -10,7 +10,7 @@ return [
'fopen' => [['shell']],
'header' => [['text']],
'igbinary_unserialize' => [['unserialize']],
-'ldap_search' => [['text']],
+'ldap_search' => [[], ['ldap'], ['ldap']],
'mysqli_query' => [[], ['sql']],
'mysqli::query' => [['sql']],
'mysqli_real_query' => [[], ['sql']],
diff --git a/docs/running_psalm/issues/TaintedLdap.md b/docs/running_psalm/issues/TaintedLdap.md
new file mode 100644
index 000000000..9f335401c
--- /dev/null
+++ b/docs/running_psalm/issues/TaintedLdap.md
@@ -0,0 +1,32 @@
+# TaintedLdap
+
+Potential LDAP injection. This rule is emitted when user-controlled input can be passed into a LDAP request.
+
+## Risk
+
+Passing untrusted user input to LDAP requests could be dangerous.
+
+If LDAP requests like these are used for login purposes, it could result in an authentication bypass. An attacker could write a filter that would evaluate to `true` for any user, and thus bruteforce credentials easily.
+
+
+## Example
+
+```php
+ return
+ */
+function ldap_escape(string $value, string $ignore = "", int $flag = 0) : string {}
diff --git a/tests/TaintTest.php b/tests/TaintTest.php
index 8e243170d..5234da94e 100644
--- a/tests/TaintTest.php
+++ b/tests/TaintTest.php
@@ -230,6 +230,13 @@ class TaintTest extends TestCase
echo $a;
}'
],
+ 'taintLdapEscape' => [
+ ' [
'getTaint();',
'error_message' => 'TaintedHtml',
],
+ 'taintedLdapSearch' => [
+ ' 'TaintedLdap',
+ ],
/*
// TODO: Stubs do not support this type of inference even with $this->message = $message.
// Most uses of getMessage() would be with caught exceptions, so this is not representative of real code.