How masking of sensitive data is achieved using slf4j framework?

て烟熏妆下的殇ゞ 提交于 2020-04-30 07:23:19

问题


I wanted to mask the sensitive data like username/password using an slf4j framework. Immediate help is appreciated. Thanks in advance.


回答1:


Assuming you're using Java/Groovy. In your log4j2.xml, add something like:

    <PatternLayout pattern="%mm"/>

then take that pattern and create a converter for it:

@Plugin(name = 'maskLog', category = 'Converter')
@ConverterKeys(['mm'])
class MaskLogConverter extends LogEventPatternConverter {

    private static final String NAME = 'mm'

    private MaskLogConverter(String[] options) {
        super(NAME, NAME)
    }

    static LogMaskingConverter newInstance(final String[] options) {
        return new LogMaskingConverter(options)
    }

    @Override
    void format(LogEvent event, StringBuilder outputMessage) {
        String message = event.message//.formattedMessage

        // Do your masking logic here

        outputMessage.append(message)
    }
}

Inside that class you can mask, transform, parse, etc. accordingly.




回答2:


Maybe this library will helpfull: owasp-security-logging

It related to OWASP Security Logging Project and provide related features:

LOGGER.info("userid={}", userid);  
LOGGER.info(SecurityMarkers.CONFIDENTIAL, "password={}", password);

The intent is to produce the following output in the log:

2014-12-16 13:54:48,860 [main] INFO - userid=joebob
2014-12-16 13:54:48,860 [main] [CONFIDENTIAL] INFO - password=***********

More you can find in Wiki




回答3:


Try this one. 1. First of all, we should create a class for handling our logs (each row)

public class PatternMaskingLayout extends PatternLayout {

private Pattern multilinePattern;
private List<String> maskPatterns = new ArrayList<>();

public void addMaskPattern(String maskPattern) { // invoked for every single entry in the xml
    maskPatterns.add(maskPattern);
    multilinePattern = Pattern.compile(
            String.join("|", maskPatterns), // build pattern using logical OR
            Pattern.MULTILINE
    );
}

@Override
public String doLayout(ILoggingEvent event) {
    return maskMessage(super.doLayout(event)); // calling superclass method is required
}

private String maskMessage(String message) {
    if (multilinePattern == null) {
        return message;
    }
    StringBuilder sb = new StringBuilder(message);
    Matcher matcher = multilinePattern.matcher(sb);
    while (matcher.find()) {
        if (matcher.group().contains("creditCard")) {
            maskCreditCard(sb, matcher);
        } else if (matcher.group().contains("email")) {
            // your logic for this case
        }
    }
    return sb.toString();
}
private void maskCreditCard(StringBuilder sb, Matcher matcher) {
    //here is our main logic for masking sensitive data
    String targetExpression = matcher.group();
    String[] split = targetExpression.split("=");
    String pan = split[1];
    String maskedPan = Utils.getMaskedPan(pan);
    int start = matcher.start() + split[0].length() + 1;
    int end = matcher.end();
    sb.replace(start, end, maskedPan);
}

}

  1. The second step is we should create appender for logback into logback.xml

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
        <layout class="com.bpcbt.micro.utils.PatternMaskingLayout">
            <maskPattern>creditCard=\d+</maskPattern> <!-- SourcePan pattern -->
            <pattern>%d{dd/MM/yyyy HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n%ex</pattern>-->
        </layout>
    </encoder>
    

  2. Now we can use logger into our code

    log.info("card context set for creditCard={}", creditCard);

  3. As a result, we will see

    one row from logs

    card context set for creditCard=11111******111

without these options, our logs would be like this row

card context set for creditCard=1111111111111



回答4:


The framework itself won't do the masking, nor should you expect it to. It's a very bad practice to pass confidential information to a reporting system. In your log.info() call, make sure to substitute the password with asterisks. There is no point in masking the username because you might as well not log anything.

log.info("Successful login: {0} ********", username);


来源:https://stackoverflow.com/questions/16775253/how-masking-of-sensitive-data-is-achieved-using-slf4j-framework

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!