【缺陷周话】第19期:LDAP 注入
字数 1429 2025-08-18 11:37:53
LDAP注入漏洞分析与防御指南
1. LDAP基础概念
LDAP(Light Directory Access Protocol)是基于X.500标准的轻量级目录访问协议,提供访问目录数据库方法的服务和协议,常用于与目录数据库组成目录服务。
目录服务的特点:
- 为查询、浏览和搜索而优化的专业分布式数据库
- 呈树状结构组织数据,类似于Linux/Unix系统中的文件目录
- 适合存储修改不频繁的数据,如公用证书、安全密钥、公司物理设备信息等
可以将LDAP理解为一种搜索协议,它类似于SQL,拥有查询语法,也存在被注入攻击的风险。
2. LDAP注入定义
LDAP注入是指客户端发送查询请求时,输入的字符串中含有一些特殊字符,导致修改了LDAP本来的查询结构,从而使得可以访问更多的未授权数据的一种攻击方式。
3. LDAP注入的危害
LDAP注入的危害主要体现在:
- 利用用户引入的参数生成恶意LDAP查询
- 通过构造LDAP过滤器来绕过访问控制
- 实现用户权限提升
- 在维持正常过滤器的情况下构造出AND、OR操作注入来获得敏感信息
近年相关漏洞案例:
- CVE-2018-12689:phpLDAPadmin 1.2.2允许通过精心设计的serverid参数或登录凭据进行LDAP注入
- CVE-2018-5730:MIT krb5 1.6+允许经过身份验证的kadmin绕过DN容器检查
- CVE-2016-8750:Apache Karaf <4.0.8未正确编码用户名,易受LDAP注入攻击
- CVE-2011-4069:PacketFence <3.0.2允许通过精心设计的用户名绕过身份验证
4. LDAP注入示例分析
4.1 缺陷代码示例
// 从TCP连接读取数据
String data = inputStream.readUTF();
// 构造LDAP查询
String ldapSearchQuery = "(cn=" + data + ")";
ctx.search(ldapSearchQuery, filter, constraints);
漏洞点分析:
- 程序从TCP连接读取数据并直接用于构造LDAP查询
- 未对用户输入的
data变量进行任何过滤或编码 - 攻击者可传入特殊字符(如
*)修改查询结构,例:"(cn=*)"可查询所有员工信息
4.2 漏洞检测
使用静态分析工具(如360代码卫士)可检测此类漏洞:
- 检测等级:高危
- 可追踪污染源和数据流向
- 能精确定位到漏洞代码行
5. LDAP注入修复方案
5.1 修复代码示例
// 使用BaseControl处理参数
BaseControl control = new BasicControl();
byte[] encodedValue = control.getEncodedValue(data);
// 使用编码后的值进行查询
String ldapSearchQuery = "(cn=" + new String(encodedValue) + ")";
ctx.search(ldapSearchQuery, filter, constraints);
修复原理:
- 使用
javax.naming.ldap.BaseControl处理参数 getEncodedValue()方法将输入数据转换为ASN.1 BER编码- 编码后的值不包含可解析的特殊字符
- 确保构造的LDAP查询结构正常
5.2 防御最佳实践
-
白名单验证
- 确保用户输入仅包含预定字符集中的字符
- 拒绝任何LDAP元字符
-
特殊字符转义
- 对必须包含LDAP元字符的输入进行转义处理
- 常见需要转义的字符:
&、|、!、=、<、>、~等 - 使用反斜杠(
\)转义特殊字符
-
编码处理
- 对NUL等特殊字符不仅要转义,还要转换为ASCII码值
- 使用专门的LDAP编码函数处理输入
-
最小权限原则
- LDAP查询账户使用最小必要权限
- 限制可返回的属性字段
-
输入验证
- 实施严格的输入长度和格式检查
- 拒绝明显恶意的输入模式
6. 总结
LDAP注入是Web应用常见的安全威胁,其根本原因是未正确处理用户输入中的LDAP元字符。通过实施严格的输入验证、使用参数编码、遵循最小权限原则等防御措施,可有效降低LDAP注入风险。开发人员应充分了解LDAP查询机制,在代码层面做好安全防护,确保目录服务的安全性。