简体   繁体   English

如何使用Log4J屏蔽日志文件中的信用卡号?

[英]How to mask credit card numbers in log files with Log4J?

Our web app needs to be made PCI compliant, ie it must not store any credit card numbers. 我们的网络应用程序需要符合PCI标准,即不得存储任何信用卡号码。 The app is a frontend to a mainframe system which handles the CC numbers internally and - as we have just found out - occasionally still spits out a full CC number on one of its response screens. 该应用程序是大型机系统的前端,它在内部处理CC号码 - 正如我们刚刚发现的那样 - 偶尔会在其响应屏幕上吐出一个完整的CC号码。 By default, the whole content of these responses are logged at debug level, and also the content parsed from these can be logged in lots of different places. 默认情况下,这些响应的全部内容都以调试级别记录,并且从这些响应中解析的内容也可以记录在许多不同的位置。 So I can't hunt down the source of such data leaks. 所以我无法追捕这些数据泄漏的来源。 I must make sure that CC numbers are masked in our log files. 我必须确保在我们的日志文件中屏蔽了CC编号。

The regex part is not an issue, I will reuse the regex we already use in several other places. 正则表达式部分不是问题,我将重用我们已在其他几个地方使用的正则表达式。 However I just can't find any good source on how to alter a part of a log message with Log4J. 但是我找不到有关如何使用Log4J更改日志消息的一部分的任何好的来源。 Filters seem to be much more limited, only able to decide whether to log a particular event or not, but can't alter the content of the message. 过滤器似乎更受限制,只能决定是否记录特定事件,但不能改变消息的内容。 I also found the ESAPI security wrapper API for Log4J which at first sight promises to do what I want. 我还发现了Log4J的ESAPI安全包装API ,它初看起来有望实现我的目标。 However, apparently I would need to replace all the loggers in the code with the ESAPI logger class - a pain in the butt. 但是,显然我需要用ESAPI记录器类替换代码中的所有记录器 - 这是一个痛苦的屁股。 I would prefer a more transparent solution. 我更喜欢更透明的解决方案。

Any idea how to mask out credit card numbers from Log4J output? 知道如何屏蔽Log4J输出的信用卡号码吗?

Update: Based on @pgras's original idea, here is a working solution: 更新:根据@ pgras的最初想法,这是一个有效的解决方案:

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);
    }
}

Notes: 笔记:

  • I mask with + rather than * , because I want to tell apart cases when the CID was masked by this logger, from cases when it was done by the backend server, or whoever else 我使用+而不是*掩码,因为我想区分CID被此记录器屏蔽的情况,以及后端服务器完成的情况,或者其他任何情况
  • I use a simplistic regex because I am not worried about false positives 我使用简单的正则表达式,因为我不担心误报

The code is unit tested so I am fairly convinced it works properly. 代码经过单元测试,所以我相信它能正常工作。 Of course, if you spot any possibility to improve it, please let me know :-) 当然,如果您发现任何改进它的可能性,请告诉我:-)

You could write your own layout and configure it for all appenders... 您可以编写自己的布局并为所有appender配置它...

Layout has a format method which makes a String from a loggingEvent that contains the logging message... Layout有一个格式方法,它从包含日志消息的loggingEvent生成一个String ...

A better implementation of credit card number masking is at http://adamcaudill.com/2011/10/20/masking-credit-cards-for-pci/ . 更好地实施信用卡号码屏蔽,请访问http://adamcaudill.com/2011/10/20/masking-credit-cards-for-pci/ You want to log the issuer and the checksum, but not the PAN (Primary Account Number). 您想记录发行者和校验和,但不记录PAN(主帐号)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM