¿Cómo enmascarar números de tarjetas de crédito en archivos de registro con Log4J?


Nuestra aplicación web debe ser compatible con PCI, es decir, no debe almacenar ningún número de tarjeta de crédito. La aplicación es una interfaz para un sistema de mainframe que maneja los números CC internamente y, como acabamos de descubrir, de vez en cuando todavía escupe un número CC completo en una de sus pantallas de respuesta. De forma predeterminada, todo el contenido de estas respuestas se registra a nivel de depuración, y también el contenido analizado de estas se puede registrar en muchos lugares diferentes. Así que no puedo cazar la fuente de tal fugas de datos. Debo asegurarme de que los números CC estén enmascarados en nuestros archivos de registro.

La parte regex no es un problema, voy a reutilizar la regex que ya usamos en varios otros lugares. Sin embargo, no puedo encontrar ninguna buena fuente sobre cómo alterar una parte de un mensaje de registro con Log4J. Los filtros parecen ser mucho más limitados, solo pueden decidir si registrar un evento en particular o no, pero no pueden alterar el contenido del mensaje. También encontré el ESAPI security wrapper API para Log4J que al principio la vista promete hacer lo que quiero. Sin embargo, aparentemente tendría que reemplazar todos los registradores en el código con la clase ESAPI logger - un dolor en el trasero. Preferiría una solución más transparente.

¿Alguna idea de cómo enmascarar los números de tarjetas de crédito de la salida Log4J?

Actualización: Basado en la idea original de @pgras, aquí hay una solución de trabajo:

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

Notas:

  • Enmascaro con + en lugar de *, porque quiero distinguir los casos cuando el CID fue enmascarado por este logger, de los casos en que fue hecho por el servidor backend, o quien sea
  • Uso una expresión regular simplista porque no me preocupan los falsos positivos

El código está probado por unidad, así que estoy bastante convencido de que funciona correctamente. Por supuesto, si encuentra alguna posibilidad de mejorarlo, por favor hágamelo saber: -)

Author: Reddy, 2010-03-17

2 answers

Puede escribir su propio diseño y configurarlo para todos los anexores...

Layout tiene un método de formato que crea una cadena a partir de un LoggingEvent que contiene el mensaje de registro...

 14
Author: pgras,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-17 11:41:09

Una mejor implementación del enmascaramiento de números de tarjetas de crédito está en http://adamcaudill.com/2011/10/20/masking-credit-cards-for-pci / . Desea registrar el emisor y la suma de verificación, pero no el PAN (Número de cuenta Principal).

 4
Author: Concrete Gannet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-23 02:23:47