Подтвердить что ты не робот

Как маскировать номера кредитных карт в журнальных файлах с помощью Log4J?

Наше веб-приложение должно быть выполнено PCI-совместимым, то есть оно не должно содержать номера кредитных карт. Приложение является интерфейсом для системы мэйнфреймов, которая обрабатывает номера CC внутри, и, как мы только что узнали, иногда все еще выплескивает полный номер CC на одном из экранов ответа. По умолчанию все содержимое этих ответов регистрируется на уровне отладки, а также анализируемый из них контент может регистрироваться во множестве разных мест. Поэтому я не могу выследить источник утечки данных. Я должен убедиться, что номера CC маскируются в наших файлах журналов.

Часть регулярных выражений не является проблемой, я буду повторно использовать регулярное выражение, которое мы уже использовали в нескольких других местах. Однако я просто не могу найти хороший источник того, как изменить часть сообщения журнала с помощью Log4J. Фильтры, по-видимому, намного более ограничены, но только могут решить, следует ли регистрировать конкретное событие или нет, но не могут изменять содержимое сообщения. Я также нашел API-интерфейс обертки ESAPI для Log4J, который на первый взгляд promises выполняет то, что я хочу. Однако, по-видимому, мне нужно будет заменить все регистраторы кода кодом 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 был замаскирован этим регистратором, из случаев, когда это было сделано сервером backend, или кем бы то ни было
  • Я использую упрощенное регулярное выражение, потому что меня не беспокоят ложные срабатывания

Код проверен модулем, поэтому я уверен, что он работает правильно. Конечно, если вы заметили какую-либо возможность улучшить его, сообщите мне: -)

4b9b3361

Ответ 1

Вы можете написать свой собственный макет и настроить его для всех приложений...

Макет имеет формат, который делает строку из loggingEvent, которая содержит сообщение регистрации...

Ответ 2

Лучшая реализация маскировки номеров кредитных карт находится в http://adamcaudill.com/2011/10/20/masking-credit-cards-for-pci/. Вы хотите зарегистрировать эмитента и контрольную сумму, но не PAN (номер первичной учетной записи).