2010-03-17 1 views
26

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

Часть регулярных выражений не является проблемой, я буду повторно использовать регулярное выражение, которое мы уже использовали в нескольких других местах. Однако я просто не могу найти хороший источник того, как изменить часть сообщения журнала с помощью Log4J. Фильтры, по-видимому, намного более ограничены, но только могут решить, следует ли регистрировать конкретное событие или нет, но не могут изменять содержимое сообщения. Я также нашел ESAPI security wrapper API для Log4J, который с первого взгляда обещает сделать то, что я хочу. Однако, по-видимому, мне нужно будет заменить все регистраторы кода кодом ESAPI logger - болью в прикладе. Я предпочел бы более прозрачное решение.

Любая идея, как замаскировать номера кредитных карт из выхода Log4J?

Update: на основе оригинальной идеи @ 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); 
    } 
} 

Примечания:

  • I маска с +, а не *, потому что я хочу сказать в случаях, когда CID был замаскирован этим регистратором, из случаев, когда это было сделано сервером backend, или кем бы то ни было
  • Я использую упрощенное регулярное выражение, потому что меня не беспокоят ложные срабатывания

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

+1

Не знаете, почему вы не позволяете супер-синтаксическому разбору события сначала вставлять, а затем фильтровать его. Вы бы избавили себя от большого количества кодирования. –

+0

Спасибо, ребята, вы спасли мою жизнь ... !! – user381878

+0

@ avok00, потому что LoggingEvent неизменен. –

ответ

13

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

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

+0

Вы можете сделать свой новый макет составным из существующего, который вы используете: делегировать все, что не соответствует вашему регулярному выражению, и затем удалите или запустите строку, содержащую номер кредитной карты –

+0

Спасибо, это кажется жизнеспособным. В этом случае я предпочел бы подклассы над агрегацией.Давайте немного поэкспериментируем с этим ... –

4

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

+2

Ну, лучше относительно :-) В этом случае я не хочу регистрировать эмитента ни контрольной суммы. Меня совсем не интересует конкретный номер карты - нам не нужно искать их в журналах или что-то еще. Вот почему мне тоже не нужны ложные срабатывания. Единственный момент в том, что ни один номер карты не попадает в журналы. Но я согласен, что в других случаях решение Адама может быть лучше. –

Смежные вопросы