【缺陷周话】第50期:日志伪造
字数 1275 2025-08-18 11:38:53
日志伪造漏洞分析与防御指南
1. 漏洞定义
日志伪造(Log Forging)是指当日志条目包含未经过授权的用户输入时,攻击者可以通过向应用程序提供包含特殊字符的内容,在日志文件中插入错误的条目。根据CWE ID 117定义,这属于"日志输出中和不当"(Improper Output Neutralization for Logs)的安全缺陷。
2. 漏洞危害
- 日志格式破坏:恶意条目会破坏日志文件格式
- 攻击轨迹掩盖:可以掩盖攻击者的入侵轨迹
- 信任边界跨越:可能跨越信任边界获取敏感数据
- XSS攻击:注入的脚本可能在使用Web浏览器查看日志时执行
- 权限提升:通过获取管理员Cookie副本获得管理员访问权限
3. 漏洞原理
攻击者利用回车符(%0a)和换行符(%0d)等特殊字符构造输入,将合法的日志条目进行拆分,从而:
- 在日志中插入伪造条目
- 将单一日志条目拆分为多个看似合法的条目
示例攻击
当用户输入:
jack%0a%0aINFO:+User+login+succeeded+for+tom
日志记录会变为:
INFO: User login failed for jack
INFO: User login succeeded for tom
4. 漏洞代码示例
缺陷代码
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
super.doGet(request, response);
String username = request.getParameter("username");
String password = request.getParameter("password");
if(isValidUser(username, password)) {
logger.info("User login succeeded for " + username);
} else {
logger.info("User login failed for " + username);
}
}
问题分析
- 直接拼接用户输入(
username)到日志语句 - 未对用户输入进行任何过滤或转义
- 允许特殊字符(如换行符)进入日志系统
5. 修复方案
修复代码示例
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
super.doGet(request, response);
String username = request.getParameter("username");
String password = request.getParameter("password");
if(isValidUser(username, password)) {
logger.info("User login succeeded for " + StringEscapeUtils.escapeJavaScript(username));
} else {
logger.info("User login failed for " + StringEscapeUtils.escapeJavaScript(username));
}
}
修复要点
- 使用
StringEscapeUtils.escapeJavaScript()对用户输入进行转义 - 转义处理会处理特殊字符,防止日志条目拆分
- 使用Apache Commons Lang库提供的工具类
6. 防御措施
输入控制
- 输入验证:假设所有输入都是恶意的
- 严格规范:拒绝任何不严格符合规范的输入
- 字段属性校验:
- 长度限制
- 输入类型检查
- 值范围验证
- 数据转换:将输入转换为符合规格的格式
输出控制
- 编码指定:明确指定日志输出的编码格式
- 特殊字符处理:
- 转义换行符(
\n)、回车符(\r) - 转义其他控制字符
- 转义换行符(
- 日志框架配置:使用安全配置的日志框架
推荐技术
- Java:
StringEscapeUtils.escapeJavaScript()(Apache Commons Lang)ESAPI.encoder().encodeForHTML()(OWASP ESAPI)
- 其他语言:使用相应语言的HTML/日志转义函数
7. 检测方法
- 静态分析:使用代码安全检测工具(如奇安信代码卫士)
- 动态测试:尝试输入包含特殊字符的测试用例
- 日志审计:检查日志中是否存在异常格式的条目
8. 最佳实践
- 最小化日志记录:只记录必要的、非敏感信息
- 敏感数据过滤:避免在日志中记录密码、令牌等敏感信息
- 日志格式标准化:使用结构化日志格式(如JSON)
- 日志监控:实施实时日志监控和异常检测
- 权限控制:限制日志文件的访问权限
9. 相关标准
- CWE:CWE-117 Improper Output Neutralization for Logs
- OWASP:
- OWASP Top 10 A1: Injection
- OWASP Logging Cheat Sheet