Search code examples
javaspring-bootloggingspring-security

Spring RestTemplate - How to remove `client_secret` from the logs?


My backend application currently leaks client_secret inside my log file. I would like to keep the log level of DEBUG except for the RestTemplate where I don't want this line to be executed.

The log line in question looks something like this:

o.s.web.client.RestTemplate : Writing [{client_id=[id-client], client_secret=[xxxxxxxxxxxxxxxxxxxxxxxxxxx], grant_type=[client_credentials], audience=[roles-api]}] as "application/x-www-form-urlencoded"

And this is how my logback-spring.xml looks like at the moment:

...
    <logger name="org.springframework.web" level="DEBUG"/>
    <Logger name="org.springframework.web.client.RestTemplate" level="INFO"/>
...

I think the DEBUG level set for org.springframework.web "overrides" the INFO level set for RestTemplate.


Solution

  • Here is what I have done to solve this issue. I've created a custom layout which processes log messages before they are written to the log files. Here is the code:

    MaskingPatternLayout.java

    package my.project.path;
    
    import ch.qos.logback.classic.PatternLayout;
    import ch.qos.logback.classic.spi.ILoggingEvent;
    
    public class MaskingPatternLayout extends PatternLayout {
    
        @Override
        public String doLayout(ILoggingEvent event) {
            String message = super.doLayout(event);
            return message.replaceAll("client_secret=\\S*", "client_secret=[****],");
        }
    }
    

    And in the logback-spring.xml I've added the following lines:

        <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
                <layout class="my.project.path.MaskingPatternLayout">
                    <pattern>${FILE_LOG_PATTERN}</pattern>
                </layout>
            </encoder>
            <file>${LOG_FILE}</file>
            <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
                ...
            </rollingPolicy>
        </appender>
    

    With these changes, my log files now contain masked client secrets and look like this:

    o.s.web.client.RestTemplate : Writing [{client_id=[id-client], client_secret=[****], grant_type=[client_credentials], audience=[roles-api]}] as "application/x-www-form-urlencoded".

    Finally, keep in mind that this is just a fix, and ideally, you should avoid logging sensitive information.