在记录之前屏蔽敏感数据 - log4j

时间:2018-03-07 03:57:56

标签: java log4j log4j2 data-masking

出于日志记录的目的,不是使用toString()方法,杰克逊的writeValueAsString(object)方法已用于我一直在为之工作的项目中。

LOGGER.info(mapper.writeValueAsString(object));

现在,我要求屏蔽日志中的密码和信用卡号等敏感信息。如果正在使用toString(),我可以从toString()方法中删除这些敏感数据。但就我而言,我找不到解决问题的简单而正确的方法。我不会改变整个事情以使用toString()

我通过使用%replace方法阅读,我可以使用预定义的模式替换我不需要登录的数据。但是,所有需要屏蔽的敏感数据都不会遵循单一模式。

我尝试拦截日志事件,查找特定信息并屏蔽它们(使用实现LogEventFactory的类)。即使它是一个可行的解决方案,我也不认为这是一个很好的解决方案,因为每次查找大字符串的数据都会花费很多。

我还有什么方法可以解决我的问题吗?采用%replace的方法是可行的吗?如果是这样,怎么样?

1 个答案:

答案 0 :(得分:0)

我认为您可以通过三种方法来解决您的问题。最有效的方法是防止将对日志敏感的数据发送到记录器,这需要您做大量的工作。

第二种方法是修改Appender。通过扩展log4j Appenders,可以修改LogEvent。

最后一种方法是修改PatternLayout。这是example

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