package org.owasp.security.logging.mask; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.Pattern; import ch.qos.logback.classic.pattern.ClassicConverter; import ch.qos.logback.classic.spi.ILoggingEvent; /** * Masking configured values in logs. To configure in you logback file here is an example: * Step 1 add conversion word * <conversionRule conversionWord="maskedMsg" converterClass="org.owasp.security.logging.mask.DefinedRegexMaskingConverter" /> * * Step 2 add to the pattern like this. There 4 pre-defined values for CompleteMask, MaskLastFour, MaskFirstFour, emailMasking * * %maskedMsg{password|signature * username, * orderNumber|giftCardNum|, * email * }" /> * * @author Rahul Agarwal * */ public class DefinedRegexMaskingConverter extends ClassicConverter { private Map<Pattern, String> patternMap = new HashMap<>(); private static final String MASK = "*****"; @Override public String convert(ILoggingEvent logEvent) { String message = logEvent.getMessage(); Set<Pattern> patternSet = patternMap.keySet(); if (message!=null && !message.equals("")) { for (Pattern pattern : patternSet) { message = pattern.matcher(message).replaceAll(patternMap.get(pattern)); } } return message; } @Override public void start() { List<String> options = getOptionList(); if (options != null && !options.isEmpty()) { // 0 = CompleteMask patternMap.put(Pattern.compile("(?x)([\"]?(" + options.get(0) + ")[\"]?\\s*[:=]{1}\\s*[\"]?)(?:[^\"\\n]+)"), "$1" + MASK); // 1 = MaskLastFour patternMap.put(Pattern.compile("(?x)([\"]?(" + options.get(1) + ")[\"]?[:=]{1}[\"]?[\\w.+/=]+)(?:[\\w.+/=]{4})"), "$1" + MASK); // 2 = MaskFirstFour patternMap.put(Pattern.compile("(?x)([\"]?(" + options.get(2) + ")[\"]?[:=]{1}[\"]?)(?:[\\w.+/=]+(?=\\w{4}))"), "$1" + MASK); // 3 = emailMasking patternMap.put(Pattern.compile("(?x)([\"]?(" + options.get(3) + ")[\"]?\\s*[:=]{1}\\s*[\"]?[\\w.]+(?=@[\\w.]+))(?:@[\\w.]+)"), "$1" + MASK); } super.start(); } }