在日志文件中隐藏敏感/机密信息

11
如何将敏感信息隐藏在日志文件中?您可以选择不记录敏感信息,但有时您可能会在错误发生或调查问题时无意中记录跟踪消息,导致敏感信息出现在日志文件中。
例如,您可能正在尝试将包含客户信用卡号的订单记录插入数据库。在数据库失败时,您可能想要记录刚刚执行的 SQL 语句。这样就可能会在日志文件中留下客户的信用卡号。
是否有一种设计范例可以标记某些敏感信息,使通用的日志记录管道可以过滤它们呢?

3
对于将这个问题推荐到serverfault.com的建议:不。这个问题是从软件角度来看的。您想确保您的软件足够智能,以帮助用户屏蔽敏感信息。实际上,我曾经从真实客户那里看到过这样一个真实需求。 - Ates Goral
你的(7年后) - Ates Goral
7个回答

7

针对这种情况,我的当前做法是记录敏感信息的哈希值。这样我们可以识别属于特定索赔(例如特定信用卡号)的日志记录,但不会让任何人有能力仅仅获取日志并将敏感信息用于恶意目的。

当然,保持一致性需要良好的编码实践。我通常选择使用对象的toString重载(在Java或.NET中),它会序列化标记有Sensitive属性的字段的值的哈希值,并将所有对象记录到日志中。

当然,SQL字符串更加棘手,但我们更依赖ORM进行数据持久化,并在各个阶段记录系统状态,然后记录SQL查询,因此这不再是一个问题。


我喜欢重写toSource的想法;这样,记录日志的代码就不需要关心正在记录什么。虽然这并没有解决内存转储的问题,但我会接受这个答案作为最佳答案,因为它直接回答了原始问题。谢谢! - Ates Goral
是的,但信用卡号的哈希值很容易被暴力破解(或构建彩虹表)。 - Andrey Fedorov
@AndreyFedorov 很好的观点,这确实是事实。最好记录这些类型的定长字符串的HMAC,并使用应用程序已知的密钥。因此,如果出现索赔,就可以再次计算HMAC进行查找,但攻击者无法通过暴力破解或构建彩虹表来还原HMAC。 - paracycle
1
是的,除非攻击者也获得了“应用已知密钥”。看起来这可能是不可避免的。 - Andrey Fedorov

5

我个人认为日志文件本身属于敏感信息,应确保对其进行访问限制。


真的!我在想,如果你是一个软件供应商,并要求客户发送系统日志文件以诊断系统崩溃等情况,那么责任会落在客户身上,先清理掉其中包含的敏感信息吗? 如果你的系统可以让客户免费获取这些文件,那不是很好吗? - Ates Goral
“限制访问”不够具体,无法为信用卡信息提供足够的保护。日志需要加密,并且访问解密密钥需要在安全策略中明确说明。 - erickson

2
记录信用卡号可能会导致PCI违规。如果您不符合PCI合规性要求,您将被收取更高的卡处理费用。要么不记录敏感信息,要么对整个日志文件进行加密。
您提出的对敏感信息进行“标记”的想法很有趣。您可以为敏感信息设置特殊数据类型,该类型包装了实际的基础数据类型。每当该对象以字符字符串形式呈现时,它只返回“***”或其他内容。
但是,这可能需要广泛的编码更改,并且需要与避免在第一时间记录敏感信息所需的警觉程度相似的意识。

1
关于 SQL 语句,如果您的编程语言支持,应该使用参数而不是将值放在语句本身中。换句话说:
select * from customers where credit_card = ?

然后将参数设置为信用卡号码。

当然,如果您计划记录带有填充参数的SQL语句,则需要其他方法来过滤敏感数据。


正确。但这仅涵盖了SQL语句。 - Ates Goral
这就是为什么我在前面加上了“特别是关于SQL语句”的前缀。它并不是要完全泛化。 - Adam Crume
知道了。实际上我是在寻找一种银弹式的解决方案,而不是逐个分析,但还是谢谢你的回答! - Ates Goral

1
在你的例子中,你应该加密信用卡号码,或者更好的做法是根本不要存储它。
比如说,如果你正在记录其他内容,比如登录信息,你可能想要明确地用*****替换密码。
然而,这样巧妙地避免了首先提出的问题的回答。一般来说,当处理敏感信息时,它应该在传输到任何形式的永久存储(无论是数据库文件还是日志文件)之前进行加密。假设坏人能够得到其中任何一个,然后相应地保护信息。

我认为加密可以是答案:一旦敏感信息进入您的系统,它就被加密并保持加密状态。因此,如果您正在进行低级别日志记录(语义无关)甚至获取内存转储,则信息将相对安全。我认为,我喜欢加密信息的想法,而不是像其他答案建议的那样加密整个日志文件。 - Ates Goral

1

如果你知道你要过滤什么,你可以在记录日志之前运行它通过一个正则表达式清理。


是的,我想到了。实际上,这可能是一个可行的解决方案,因为总会有一些不同类型的“敏感”字符串,你可以用正则表达式来识别它们。 - Ates Goral

0
请参考这个工具,它是专门为此用例创建的。
如果您只想在记录过程中屏蔽选定的字段,并保留其他字段值不变,则可以尝试使用此方法。

https://github.com/senthilaru/sp-util

<dependency>
    <groupId>com.immibytes</groupId>
    <artifactId>sp-utils</artifactId>
    <version>1.0.0-RELEASE</version>
</dependency>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接