[JAVA] Masquer les informations confidentielles dans les messages du journal avec Logback

Aperçu

La condition est que la cible du masque puisse être extraite avec une expression régulière, mais la chaîne de caractères peut être remplacée par ** % replace ** dans les paramètres de Logback.

Utilisez la fonction de expression régulière Java et la référence de la sous-chaîne capturée. Ensuite, vous pouvez masquer dans des conditions plus difficiles que l'exemple ci-dessus. Voici un exemple et le code réel.

Exemple

Dans le journal suivant, l'ID utilisateur, le jeton et l'ID de ressource sont affichés dans * tous le même format * (32 chiffres en hexadécimal). Parmi ceux-ci, je souhaite masquer les ** jetons uniquement **.

Exemple de journal


2020-11-14T09:30:52.774+09:00 [main] INFO com.example.Main - UserID: 35f44b06a3cf8dab8355eb8ba5844c73, Token: b9656056c799ab9ba19cebe12b49992b, ResourceID: 945c4f63c61f1bc7ba632fe0ce25aa0d

Paramètres de connexion


<configuration debug="true">
	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
		<encoder>
			<pattern>%date{yyyy-MM-dd'T'HH:mm:ss.SSSXXX} [%thread] %level %logger - %message%n</pattern>
		</encoder>
	</appender>

	<root level="INFO">
		<appender-ref ref="STDOUT" />
	</root>
</configuration>

Méthode

Si vous souhaitez extraire la partie de jeton avec une expression régulière, vous pouvez utiliser "ce qui est écrit juste avant Token" dans cet exemple. (Si vous essayez de porter un jugement strict dans chaque situation, vous ne pouvez pas simplement utiliser des expressions régulières)

Réécrivez % message comme suit.

%replace(%message){'((?i:token).{0,10}?)\b\p{XDigit}{32}\b','$1****'}

Ensuite, le journal sera comme suit. Seule la partie jeton est «****», et les autres n'ont pas changé.

2020-11-14T09:43:31.724+09:00 [main] INFO com.example.Main - UserID: 5457645aaa75b97eb9e2c7b0aec79ca6, Token: ****, ResourceID: c194b0155ac7ece290092c1ee2a73948

% replace prend des parenthèses et deux arguments [String # replaceAll ()](https://docs.oracle.com/javase/jp/8/docs/api/java/lang/ Vous pouvez le voir comme le récepteur et 2 arguments de String.html # replaceAll-java.lang.String-java.lang.String-).

Si vous faites de votre mieux avec les expressions régulières, vous pouvez dire: «Laissez 4 chiffres avant et après le jeton».

(Supplément) Détails des expressions régulières

Lors de la conversion au format JSON avec Logstash

(Il semble qu'il existe un paramètre de traitement de masque dans Logstash, mais cela n'a pas encore été étudié)

Étant donné que les paramètres de Logback sont écrits en JSON, il est nécessaire ** d'échapper à la barre oblique inverse **. (Sinon, \ b est reconnu comme un retour arrière et \ p est reconnu comme un échappement illégal)

Paramètres (partiels)


{
	"timestamp": "%date{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}",
	"thread": "%thread",
	"level": "%level",
	"logger": "%logger",
	"message": "%replace(%message){'((?i:token).{0,10}?)\\b\\p{XDigit}{32}\\b','$1****'}"
}

Journal


{"timestamp":"2020-11-14T11:31:38.259+09:00","thread":"main","level":"INFO","logger":"com.example.Main","message":"UserID: c610e22e634ed2ff9f1bb27afc81e638, Token: ****, ResourceID: de343ea6405a8c559043c3e3e84f9bcd"}

(Annexe) Code expérimental

Le code utilisé pour cette expérience est le suivant.

pom.xml


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>org.example</groupId>
	<artifactId>logback-sample</artifactId>
	<version>1.0-SNAPSHOT</version>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>8</source>
					<target>8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>

	<dependencies>
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<version>1.2.3</version>
		</dependency>
		<dependency>
			<groupId>net.logstash.logback</groupId>
			<artifactId>logstash-logback-encoder</artifactId>
			<version>6.4</version>
		</dependency>
	</dependencies>
</project>

src/main/resources/logback.xml


<configuration debug="true">
	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
		<encoder>
			<pattern>%date{yyyy-MM-dd'T'HH:mm:ss.SSSXXX} [%thread] %level %logger - %replace(%message){'((?i:token).{0,10}?)\b\p{XDigit}{32}\b','$1****'}%n</pattern>
		</encoder>
	</appender>

	<appender name="STDOUT_JSON" class="ch.qos.logback.core.ConsoleAppender">
		<!-- https://github.com/logstash/logstash-logback-encoder -->
		<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
			<providers>
				<pattern>
					<pattern>
						{
						"timestamp": "%date{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}",
						"thread": "%thread",
						"level": "%level",
						"logger": "%logger",
						"message": "%replace(%message){'((?i:token).{0,10}?)\\b\\p{XDigit}{32}\\b','$1****'}"
						}
					</pattern>
				</pattern>
			</providers>
		</encoder>
	</appender>

	<root level="INFO">
		<appender-ref ref="STDOUT" />
		<appender-ref ref="STDOUT_JSON" />
	</root>
</configuration>

src/main/java/com/example/Main.java


package com.example;

public class Main {
	private static final org.slf4j.Logger log =
			org.slf4j.LoggerFactory.getLogger(Main.class);

	public static void main(String[] args) {
		log.info("UserID: {}, Token: {}, ResourceID: {}", hex(), hex(), hex());
	}

	private static String hex() {
		return new java.util.Random().ints(16, 0, 256)
				.mapToObj(x -> String.format("%02x", x))
				.reduce("", (a, b) -> a + b);
	}
}

Recommended Posts

Masquer les informations confidentielles dans les messages du journal avec Logback
Élément 75: inclure les informations de capture des échecs dans les messages détaillés
Créer un CSR avec des informations étendues en Java
Journal de sortie vers un fichier externe avec slf4j + logback avec Maven