LDAP注入攻击
LDAP注入攻击是一种利用基于用户输入构建LDAP语句的Web应用程序的攻击。当应用程序未能正确清理用户输入时,可以通过类似于SQL注入的技术来修改LDAP语句,从而执行未经授权的操作。
什么是LDAP注入攻击?
LDAP(轻量级目录访问协议)是一种用于访问和维护分布式目录信息服务的协议。Web应用程序通常使用LDAP来管理用户和权限。当应用程序通过用户输入来构建LDAP查询时,如果没有进行充分的输入验证,攻击者可以通过特制的输入修改LDAP查询,达到未授权访问或篡改数据的目的。
防止LDAP注入攻击的有效方法
除了使用通用输入验证,以下几种方法可以有效防止LDAP注入攻击:
1. 避免创建依赖于不受信任数据的LDAP查询
不要直接使用外部输入来构建LDAP查询。相反,应该从LDAP服务器检索用户对象,并在应用程序代码中检查其属性。例如:
// 从LDAP服务器检索用户对象并在应用程序中检查属性
DirContext ctx = new InitialDirContext(env);
String managerName = request.getParameter("managerName");
// 检索所有向该经理汇报的员工
EqualsFilter filter = new EqualsFilter("manager", managerName);
NamingEnumeration employees = ctx.search("ou=People,dc=example,dc=com", filter.toString());
2. 到达时过滤输入
必须从用户输入中过滤掉危险字符,如 ( , ) , ! , | , & , * 等。这可以通过使用白名单方式来确保输入只包含有效字符。例如:
String userSN = "Sherlock Holmes"; // 有效
String userPassword = "secret2"; // 有效
if (!userSN.matches("[\\w\\s]*") || !userPassword.matches("[\\w]*")) {
throw new IllegalArgumentException("Invalid input");
}
String filter = "(&(sn = " + userSN + ")(userPassword=" + userPassword + "))";
3. 使用自动防护框架
使用能够自动防止LDAP注入的框架,例如Spring框架的EqualsFilter类:
DirContext ctx = new InitialDirContext(env);
String managerName = request.getParameter("managerName");
// 检索所有向该经理汇报的员工
EqualsFilter filter = new EqualsFilter("manager", managerName);
NamingEnumeration employees = ctx.search("ou=People,dc=example,dc=com", filter.toString());
4. 使用额外防御:最低权限原则
为了最大限度地减少LDAP注入攻击的潜在损害,应该尽量减少分配给LDAP绑定账户的权限。确保LDAP账户只有执行必要操作的最低权限,以限制攻击者在成功注入后的操作范围。
代码示例
Java代码示例
此合规解决方案使用白名单来清理用户输入,以确保过滤字符串仅包含有效字符。在此代码中,用户sn
可能只包含字母和空格,而密码可能只包含字母数字字符:
// 有效的用户输入
String userSN = "Sherlock Holmes"; // 有效
String userPassword = "secret2"; // 有效
// ... LDAPInjection.searchRecord() 的开始 ...
sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
String base = "dc=example,dc=com";
if (!userSN.matches("[\\w\\s]*") || !userPassword.matches("[\\w]*")) {
throw new IllegalArgumentException("Invalid input");
}
String filter = "(&(sn = " + userSN + ")(userPassword=" + userPassword + "))";
// ... LDAPInjection.searchRecord() 的其余部分 ...
C#代码示例
.NET Anti XSS(目前的Encoder类)有LDAP编码功能,包括Encoder.LdapFilterEncode(string)
和Encoder.LdapDistinguishedNameEncode(string)
:
string unsafeInput = "user input with unsafe characters";
string safeLdapFilter = Encoder.LdapFilterEncode(unsafeInput);
string safeLdapDN = Encoder.LdapDistinguishedNameEncode(unsafeInput, true, true);
参考链接
- LINQ to Active Directory:提供在构建LDAP查询时自动进行LDAP编码的功能。
- Spring Framework Documentation:了解如何使用Spring框架中的功能防止LDAP注入。
- OWASP LDAP Injection Prevention Cheat Sheet:详细介绍LDAP注入的预防方法。
- Microsoft .NET Documentation:了解如何在.NET中使用Encoder类进行LDAP编码。