Java 如何用Log4J屏蔽日志文件中的信用卡号?
我们的web应用程序需要符合PCI标准,即它不能存储任何信用卡号。该应用程序是一个大型机系统的前端,该系统在内部处理抄送号码,正如我们刚刚发现的那样,偶尔仍会在其响应屏幕上显示完整的抄送号码。默认情况下,这些响应的全部内容都记录在调试级别,从中解析的内容也可以记录在许多不同的地方。所以我无法找到这些数据泄露的来源。我必须确保抄送号码在我们的日志文件中被屏蔽 regex部分不是问题,我将重用我们在其他几个地方已经使用的regex。然而,关于如何使用Log4J修改日志消息的一部分,我找不到任何好的来源。过滤器似乎更加有限,只能决定是否记录特定事件,但不能改变消息的内容。我还发现了Log4J的功能,乍一看它承诺做我想做的事情。然而,显然,我需要用ESAPI logger类替换代码中的所有记录器——这是一个令人头痛的问题。我更喜欢一个更透明的解决方案 知道如何从Log4J输出中屏蔽信用卡号码吗? 更新:基于@pgras的原始想法,这里有一个可行的解决方案:Java 如何用Log4J屏蔽日志文件中的信用卡号?,java,log4j,credit-card,mask,Java,Log4j,Credit Card,Mask,我们的web应用程序需要符合PCI标准,即它不能存储任何信用卡号。该应用程序是一个大型机系统的前端,该系统在内部处理抄送号码,正如我们刚刚发现的那样,偶尔仍会在其响应屏幕上显示完整的抄送号码。默认情况下,这些响应的全部内容都记录在调试级别,从中解析的内容也可以记录在许多不同的地方。所以我无法找到这些数据泄露的来源。我必须确保抄送号码在我们的日志文件中被屏蔽 regex部分不是问题,我将重用我们在其他几个地方已经使用的regex。然而,关于如何使用Log4J修改日志消息的一部分,我找不到任何好的来
public class CardNumberFilteringLayout extends PatternLayout {
private static final String MASK = "$1++++++++++++";
private static final Pattern PATTERN = Pattern.compile("([0-9]{4})([0-9]{9,15})");
@Override
public String format(LoggingEvent event) {
if (event.getMessage() instanceof String) {
String message = event.getRenderedMessage();
Matcher matcher = PATTERN.matcher(message);
if (matcher.find()) {
String maskedMessage = matcher.replaceAll(MASK);
@SuppressWarnings({ "ThrowableResultOfMethodCallIgnored" })
Throwable throwable = event.getThrowableInformation() != null ?
event.getThrowableInformation().getThrowable() : null;
LoggingEvent maskedEvent = new LoggingEvent(event.fqnOfCategoryClass,
Logger.getLogger(event.getLoggerName()), event.timeStamp,
event.getLevel(), maskedMessage, throwable);
return super.format(maskedEvent);
}
}
return super.format(event);
}
}
注:
- 我用
屏蔽而不是+
,因为我想区分此记录器屏蔽CID的情况、后端服务器屏蔽CID的情况或其他情况*
- 我使用了一个简单的正则表达式,因为我不担心误报
Layout有一种格式化方法,可以从包含日志消息的loggingEvent生成一个字符串…更好的信用卡号码屏蔽实现是在。
您希望记录发卡机构和校验和,而不是PAN(主帐号)。您可以将新布局与您正在使用的现有布局组合:将与正则表达式不匹配的任何内容委托给它,然后删除或删除包含信用卡号的行。银行,这似乎是可行的。尽管在这种情况下,我更喜欢子类化而不是聚合。让我们对此进行一点实验……不确定为什么不让超级用户先将事件解析为字符串,然后再对其进行过滤。你们可以省下很多代码。谢谢你们-你们救了我的命@avok00,因为LoggingEvent是不可变的。PCI DSS 3.0允许最多显示BIN和最后四个BIN。当您有大量流量时,最好使用那些允许的最大参数进行屏蔽。这可以通过更改这两行来实现<代码>私有静态最终字符串掩码=“$1+3”代码>
private static final Pattern=Pattern.compile(([0-9]{6})([0-9]{6,10})([0-9]{4})”代码>好吧,更好是相对的:-)在这种情况下,我不想记录颁发者,也不想记录校验和。我对具体的卡号一点也不感兴趣——我们不需要在日志或任何东西中搜索它们。这就是为什么我也不在乎假阳性。唯一的一点是,没有完整的卡号会进入日志。但我同意,在其他情况下,亚当的解决方案可能更好。