日志是发现错误和调试代码的便捷工具。除了日志的功能方面,从 JAVA 安全的角度来看,日志也很重要, 当发生安全漏洞时,你的日志文件是寻找所发生事件线索的第一个位置。
日志的质量至关重要。从 Java 安全的角度来看,记录太多或太少的信息都可能是灾难性的。 在本文中,我将引导你通过一种实用的 Java 日志记录方法——我们应该记录什么,我们不应该记录什么。
我们应该记录什么?
这是谁干的?识别发出此请求的用户或系统。如果可能,使用用户 ID 和 IP 地址。
到底是怎么回事?这是什么日志语句。许多开发人员已经认识到不同的日志级别来注释消息的重要性(ERROR、WARN、INFO、DEBUG、TRACE)。区分功能日志记录、安全日志记录,甚至审计日志记录(如果适用)是明智的。
在哪发生的?确定位置。你通常为每个类定义一个记录器,所以这已经是一个好的开始。但是,我们也需要知道具体的方法。此外,我们想知道特定的节点,例如,如果你正在使用微服务架构。
它是什么时候发生的?时间是必不可少的,因此请确保记录时间戳。请注意时区差异,更重要的是,每年更改两次时区。我的建议是始终以 UTC 输出,所以每个人都很清楚。
为什么会这样? “为什么”通常是你需要找出的。你不能总是在一条日志中捕捉到这一点。在某些情况下,这是显而易见的。如果是这样,请将其作为消息的一部分。很多时候,只有看到日志之间的关系,我们才能解释“为什么”。因此,请确保你的日志消息绝对清晰。
这是怎么发生的?就像“为什么”一样,“如何”通常不能在一个陈述中被抓住。因此,消息之间的关联,尤其是在基于服务的架构中,是极其重要的。为此,你应该为每个具有出站接口的服务中的每个传入请求创建一个唯一的关联 ID。获得此 ID 后,应将其记录在每个语句中。如果你需要将此 ID 传输到另一个服务,你可以使用特定的 HTTP 标头 X-Correlation-ID 来关联并保持无状态。
我们不应该记录什么?
记录太多信息与记录太少一样有害。你不希望你的日志被在生产中无用的信息淹没。因此,应始终将生产系统上的日志级别设置为合适的级别,例如 WARN 或 ERROR。
作为开发的一部分,工程师将记录可能包含个人数据的敏感实体,以便调试应用程序。尽管我们应该致力于防止这种情况发生,但内部调试消息应该具有适当的日志级别——例如,DEBUG 或 TRACE——并且不应该在生产环境中可见。
作为一般规则,应用程序不应泄露任何特定于应用程序或特定于用户的数据——攻击者可以使用这些数据。此外,通过暴露个人信息,你很可能不符合隐私法规。即使只有内部人员可以访问日志,这也是单点故障。因此,我们根本不希望这些信息落入坏人之手。
开发时,请考虑你需要记录的内容。我们是否需要记录内部 ID、未加密密码或某人的信用卡详细信息?注意不要在 Java 中输出完整的数据对象,因为输出取决于该特定对象的 toString() 方法。
通过记录个人信息以进行调试,我们规避了我们自己的许多安全策略——不完全记录这些类型的信息是明智的。如果我们需要记录特定数据,请确保设置正确的日志级别,例如 DEBUG。你还应该将生产系统的日志级别设置为更高的级别,例如 WARN。
日志记录不是你只需要做的事情。 仔细查看你记录的内容、记录时间和使用日志,对于进行快速研究或干预至关重要。尽管预防胜于治疗,但总有可能有人破坏了你的系统,而你希望防止进一步的损害。