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

t40tm48m  于 2022-11-06  发布在  其他
关注(0)|答案(1)|浏览(206)

为了记录日志,我一直在工作的项目中使用了Jackson的writeValueAsString(object)方法,而不是使用toString()方法。

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

现在,我需要屏蔽日志中的敏感信息,如密码和信用卡号。如果使用了toString(),我可以从toString()方法中删除这些敏感数据。但在我的情况下,我找不到这样简单而正确的方法来解决我的问题。我不处于可以将整个事情也改为使用toString()的情况。
我读到,通过使用%replace方法,我可以使用预定义的模式替换不需要登录的数据。但所有需要屏蔽的敏感数据不会遵循单一模式。
我尝试拦截日志事件,查找特定的信息并屏蔽它们(使用实现LogEventFactory的类)。尽管这是一个有效的解决方案,但我不认为这是一个好的解决方案,因为每次查找大字符串中的数据都会花费成本。
有没有什么方法是我还没有遇到过的,可以解决我的问题?使用%replace的方法是可行的吗?如果是,怎么做?

bwntbbo3

bwntbbo31#

我认为有三种方法可以解决你的问题,你都涵盖了。最有效的方法是防止日志敏感数据的记录器,你需要一堆的工作来做。
第二种方法是修改Appender,通过扩展log4j Appender来修改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);
    }
}

相关问题