如何解决 java spring boot 应用程序中的安全审计查找日志注入

Posted

技术标签:

【中文标题】如何解决 java spring boot 应用程序中的安全审计查找日志注入【英文标题】:How to resolve security audit finding log injection in java spring boot application 【发布时间】:2022-01-23 15:39:20 【问题描述】:

我正在尝试通过使用 lombok extern Slf4j 记录来获取异常详细信息。但是在覆盖率扫描中发现了一个问题,如下所示。

这是一项安全审计结果。 CID 227846(第 1 个,共 1 个):日志注入 (LOG_INJECTION)。受污染的字符串 ex 存储在日志中。这可能允许攻击者伪造日志消息以混淆自动日志解析工具或试图诊断攻击或其他问题的人。该值在字节码中使用不安全,无法显示。 可以通过验证用户可控输入是否符合预期来解决日志注入漏洞。

log.error(Constants.EXCEPTION_OCCURRED_MSG, ex);

我很少找到解决此问题的方法。 ESAPI 或 Apache log4j 审计是否适合此处。请提出建议。

【问题讨论】:

【参考方案1】:

我想我需要更多关于该错误到底在寻找什么的详细信息。例如,如果担心与“ex”相关的异常消息包含 PII 或其他可能记录的敏感信息,那么除非您可以控制引发的异常,否则这将更加困难。 OTOH,如果控件正在插入攻击者,则可以插入类似 Log4shell 漏洞的东西,该漏洞攻击了自 2013 年以来(显然)没有人意识到正在发生的不安全反序列化,这不是可以轻松防御的东西,如果有的话,因为问题是在底层日志系统中,用于类似的东西。 通常,解决此问题的最佳方法是与安全审核员交谈,并询问他们具体他们会考虑采取哪些补救措施。那是他们期望的什么样的清理或验证?此外,您应该了解,在获得管理层批准后,您通常可以在某处记录风险,然后决定“接受”。帮助您的管理层了解大多数“日志注入”漏洞并不像我们在最近的一系列 Log4J 2 漏洞中看到的那样严重。只是在过去一个月左右的时间里,Log4Shell 漏洞利用让每个人都处于紧张状态。如果您决定接受风险,您可能希望在定期审查的“风险登记册”中对其进行跟踪,但您也希望在审计工具中将其标记为“已接受风险”。

我自己不知道很多更具体的细节,恐怕我无法给你更具体的答案。我愿意尝试在不同的论坛中提供更多帮助,让我的 ESAPI 同事参与进来。特别是对 ESAPI Logger 进行了重写的 Jeremiah Stacey 可能有一些想法,但我认为他不会监控 SO,因此电子邮件可能是一个更好的论坛。

希望能有所帮助。 -凯文

【讨论】:

【参考方案2】:

我不能对 Apache Log4J Audit 说太多,因为我从来没有看过它(尽管 20 秒浏览其主页似乎表明它更像是一种结构化日志记录然后 SIEM 将知道如何解析的消息,而不是进行过滤/编码等的任何“安全”日志记录)。至于 ESAPI,虽然 ESAPI 确实在一定程度上处理了“安全日志记录”,但 IIRC(未验证)它对 异常 的作用并不大。主要是 ESAPI 的日志记录信任异常堆栈,更关注错误消息本身。通常对于安全设计,除非经过验证,否则绝不应将用户数据放在异常消息中。但是这种验证不是一般的日志框架可以做到的。对于日志框架,它必须能够处理任何Exception(或者可能是Throwable,YMMV)和任何字符串,当它到达日志框架时,具体的上下文是应该如何验证某事是丢了。

ESAPI 的“安全日志记录”主要包括将“\r”或“\n”字符替换为“_”(以防止日志注入)作为记录的“消息”字符串(不是异常)的一部分,并可选择执行 html消息上的实体输出编码(以防有人打算在浏览器中仔细阅读日志消息;目的是防止通过日志消息进行 XSS 攻击)。尽管您可以通过足够的努力将其扩展为做其他事情(例如,过滤掉 ESC 序列等)。

最终,为了完全防止日志注入攻击,您必须在记录之前验证所有不受信任的数据。 ESAPI 的Validator 可以为您提供帮助,但您作为开发人员仍然需要在适当的时候使用适当的验证标准调用它。

添加于 12/29/201:就使用 ESAPI 的 Validator 而言,我并不是要使用 ESAPI 的 Encoder 进行输出编码。相反,您将创建一个正则表达式来将您的预期数据列入白名单,并将其放入您的 validation.properties 中,然后调用 Validator.getValidInput() 方法之一。如果您没有抛出ValidationException,则根据您的正则表达式,输出应该是“安全的”。 (请注意,您可能需要在多个地方使用许多不同的正则表达式来执行此操作。)OTOH,我不能保证会让您的 Coverity 扫描满意,因为它不可能知道您提供的正则表达式是否是一个合适的或不合适的。 (我也不认为它会做那么深入的数据流分析以认为它“安全”可以使用。)

【讨论】:

我对凯文的回答无能为力。如果 Coverity 在该调用上出现标记,那么它一定是在寻找用户输入进入堆栈跟踪的方式,从我遥远的角度来看,我发现很难想象如何以这种方式使用用户数据除了让用户指定要由类加载器加载的类之外,这是一个更糟糕的问题。因此,调查用户如何操纵该异常,您就有了答案。不要只是通过调用库来安抚 SAST 工具的人! 我尝试使用 ESAPI 但没有运气。可能是我错过了一些东西。我在类路径中包含了 ESAPI.properties 和 validation.properties 文件。使用 ESAPI 编码器处理异常,如 ESAPI.encoder().encodeForHTML(ex.toSring())。我在validation.properties 文件中遗漏了什么? 在 ESAPI.properties 中有一个属性几乎可以免费为您提供 HTML 输出编码。只需设置 Logger.LogEncodingRequired=true。默认为假。 @KevinW.Wall 感谢您快速详细的回复。我正在记录的属性没有验证限制。这就是我需要编码的地方。能够解决大部分问题并留下一个。您能否分享任何与 ESAPI 相关的文档,其中包含完整的详细信息。 @KevinW.Wall 我看到 ESAPI 库具有在 Veracode 中标识的高风险许可证。请对此发表评论。这会在以后产生任何问题吗?

以上是关于如何解决 java spring boot 应用程序中的安全审计查找日志注入的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot如何解决Whitelabel错误页面

在单个 Tomcat 服务器中部署多个 Spring Boot 应用程序意味着显示异常。如何解决这个问题?

使用 Spring Boot Java 端口 8080 上的 Tomcat 失败

如何解决此问题 Spring Boot 应用程序?

如何查看spring boot 支持的jetty版本

无法在 Spring Boot 中实现 Drools KieSession Persistence