代码之家  ›  专栏  ›  技术社区  ›  Péter Török

如何用log4j屏蔽日志文件中的信用卡号码?

  •  27
  • Péter Török  · 技术社区  · 16 年前

    我们的Web应用程序需要符合PCI,即它不能存储任何信用卡号码。这个应用程序是主机系统的前端,主机系统内部处理CC号码,正如我们刚刚发现的那样,偶尔还会在其中一个响应屏幕上吐出完整的CC号码。默认情况下,这些响应的全部内容都是在调试级别记录的,并且从这些响应解析的内容也可以记录在许多不同的地方。所以我找不到这些数据泄露的源头。我必须确保在我们的日志文件中隐藏CC编号。

    regex部分不是问题,我将重用我们已经在其他几个地方使用的regex。但是,对于如何使用log4j修改日志消息的一部分,我找不到任何好的来源。过滤器似乎更为有限,只能决定是否记录特定事件,但不能更改消息的内容。我也发现了 ESAPI security wrapper API 对于log4j,它一眼就能保证做我想做的事。但是,显然我需要用esapi logger类替换代码中的所有记录器——这是一个麻烦。我更喜欢更透明的解决方案。

    知道如何从log4j输出中屏蔽信用卡号码吗?

    更新: 基于@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);
        }
    }
    

    笔记:

    • 我戴面具 + 而不是 * ,因为我想区分CID被此记录器屏蔽的时间、后端服务器屏蔽的时间或其他任何情况。
    • 我使用简单的正则表达式,因为我不担心误报

    代码经过了单元测试,所以我相当确信它可以正常工作。当然,如果你发现有改进的可能,请告诉我:—)

    2 回复  |  直到 9 年前
        1
  •  14
  •   pgras    16 年前

    你可以自己写 layout 并为所有附加程序配置它…

    layout有一个格式方法,它从包含日志消息的日志事件生成字符串…

        2
  •  4
  •   Concrete Gannet    14 年前

    更好地实现信用卡号码屏蔽是在 http://adamcaudill.com/2011/10/20/masking-credit-cards-for-pci/ . 您希望记录颁发者和校验和,但不记录PAN(主帐号)。