Skip to content

Commit 58176d0

Browse files
committed
CS: added extra guidance in recommendation section for LDAPInjection
1 parent c475bed commit 58176d0

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
lines changed

LDAPInjection.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# LDAP query built from user-controlled sources
2+
If an LDAP query is built using string concatenation, and the components of the concatenation include user input, a user is likely to be able to run malicious LDAP queries.
3+
4+
5+
## Recommendation
6+
If user input must be included in an LDAP query, it should be escaped to avoid a malicious user providing special characters that change the meaning of the query. If possible, use an existing library, such as the AntiXSS library. One may also make their own encoder filters \`LdapEncode\` following \[RFC 4515\](https://datatracker.ietf.org/doc/html/rfc4515\#section-3) standards.
7+
8+
9+
## Example
10+
In the following examples, the code accepts an "organization name" and a "username" from the user, which it uses to query LDAP to access a "type" property.
11+
12+
The first example concatenates the unvalidated and unencoded user input directly into both the DN (Distinguished Name) and the search filter used for the LDAP query. A malicious user could provide special characters to change the meaning of these queries, and search for a completely different set of values.
13+
14+
The second example uses the Microsoft AntiXSS library to encode the user values before they are included in the DN and search filters. This ensures the meaning of the query cannot be changed by a malicious user.
15+
16+
17+
```csharp
18+
using Microsoft.Security.Application.Encoder
19+
using System;
20+
using System.DirectoryServices;
21+
using System.Web;
22+
23+
public class LDAPInjectionHandler : IHttpHandler
24+
{
25+
public void ProcessRequest(HttpContext ctx)
26+
{
27+
string userName = ctx.Request.QueryString["username"];
28+
string organizationName = ctx.Request.QueryString["organization_name"];
29+
// BAD: User input used in DN (Distinguished Name) without encoding
30+
string ldapQuery = "LDAP://myserver/OU=People,O=" + organizationName;
31+
using (DirectoryEntry root = new DirectoryEntry(ldapQuery))
32+
{
33+
// BAD: User input used in search filter without encoding
34+
DirectorySearcher ds = new DirectorySearcher(root, "username=" + userName);
35+
36+
SearchResult result = ds.FindOne();
37+
if (result != null)
38+
{
39+
using (DirectoryEntry user = result.getDirectoryEntry())
40+
{
41+
ctx.Response.Write(user.Properties["type"].Value)
42+
}
43+
}
44+
}
45+
46+
// GOOD: Organization name is encoded before being used in DN
47+
string safeOrganizationName = Encoder.LdapDistinguishedNameEncode(organizationName);
48+
string safeLDAPQuery = "LDAP://myserver/OU=People,O=" + safeOrganizationName;
49+
using (DirectoryEntry root = new DirectoryEntry(safeLDAPQuery))
50+
{
51+
// GOOD: User input is encoded before being used in search filter
52+
string safeUserName = Encoder.LdapFilterEncode(userName);
53+
DirectorySearcher ds = new DirectorySearcher(root, "username=" + safeUserName);
54+
55+
SearchResult result = ds.FindOne();
56+
if (result != null)
57+
{
58+
using (DirectoryEntry user = result.getDirectoryEntry())
59+
{
60+
ctx.Response.Write(user.Properties["type"].Value)
61+
}
62+
}
63+
}
64+
}
65+
}
66+
67+
```
68+
69+
## References
70+
* OWASP: [LDAP Injection Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/LDAP_Injection_Prevention_Cheat_Sheet.html).
71+
* OWASP: [Preventing LDAP Injection in Java](https://www.owasp.org/index.php/Preventing_LDAP_Injection_in_Java).
72+
* Common Weakness Enumeration: [CWE-90](https://cwe.mitre.org/data/definitions/90.html).

csharp/ql/src/Security Features/CWE-090/LDAPInjection.qhelp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ is likely to be able to run malicious LDAP queries.</p>
1212
<p>If user input must be included in an LDAP query, it should be escaped to
1313
avoid a malicious user providing special characters that change the meaning
1414
of the query. If possible, use an existing library, such as the AntiXSS
15-
library.</p>
15+
library. One may also make their own encoder filter <code>`LdapEncode`</code> following RFC 4515 standards.</p>
1616
</recommendation>
1717

1818
<example>
@@ -35,5 +35,6 @@ the query cannot be changed by a malicious user.</p>
3535
<references>
3636
<li>OWASP: <a href="https://cheatsheetseries.owasp.org/cheatsheets/LDAP_Injection_Prevention_Cheat_Sheet.html">LDAP Injection Prevention Cheat Sheet</a>.</li>
3737
<li>OWASP: <a href="https://www.owasp.org/index.php/Preventing_LDAP_Injection_in_Java">Preventing LDAP Injection in Java</a>.</li>
38+
<li>RFC 4515: <a href="https://datatracker.ietf.org/doc/html/rfc4515#section-3">String Search Filter Definition</a>.</li>
3839
</references>
3940
</qhelp>

0 commit comments

Comments
 (0)