如何使用Log4J屏蔽日志文件中的信用卡号? [英] How to mask credit card numbers in log files with Log4J?

查看:222
本文介绍了如何使用Log4J屏蔽日志文件中的信用卡号?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们的网络应用需要符合PCI标准,即不得存储任何信用卡号码。该应用程序是一个大型机系统的前端,它在内部处理CC号码 - 正如我们刚刚发现的那样 - 偶尔会在其一个响应屏幕上吐出一个完整的CC号码。默认情况下,这些响应的全部内容都以调试级别记录,并且从这些响应中解析的内容也可以记录在许多不同的位置。所以我无法追捕这些数据泄漏的来源。我必须确保在我们的日志文件中屏蔽了CC编号。

Our web app needs to be made PCI compliant, i.e. it must not store any credit card numbers. 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. 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.

正则表达式部分不是问题,我将重用我们已在其他几个地方使用的正则表达式。但是我找不到有关如何使用Log4J更改日志消息的一部分的任何好的来源。过滤器似乎更受限制,只能决定是否记录特定事件,但不能改变消息的内容。我还发现Log4J的 ESAPI安全包装API 乍看之下做我想做的事。但是,显然我需要用ESAPI记录器类替换代码中的所有记录器 - 这是一个痛苦的屁股。我希望有一个更透明的解决方案。

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. 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. However, apparently I would need to replace all the loggers in the code with the ESAPI logger class - a pain in the butt. I would prefer a more transparent solution.

知道如何屏蔽Log4J输出的信用卡号码吗?

更新:根据@ pgras最初的想法,这是一个有效的解决方案:

Update: Based on @pgras's original idea, here is a working solution:

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被这个记录器屏蔽的情况,从后端服务器完成的情况,或者其他人

  • 我使用简单的正则表达式,因为我不担心错误积极的

  • 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
  • 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 :-)

推荐答案

你可以写自己的< a href =http://logging.apache.org/log4j/1.2/apidocs/index.html\"rel =noreferrer>布局并为所有appender配置...

You could write your own layout and configure it for all appenders...

布局有一种格式方法,它从包含日志消息的loggingEvent生成一个String ...

Layout has a format method which makes a String from a loggingEvent that contains the logging message...

这篇关于如何使用Log4J屏蔽日志文件中的信用卡号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆