jsonlogginglogstashlogbacklogstash-logback-encoder

Logstash logback encoder not masking nested field


I'm trying to using the MaskingJsonGeneratorDecorator to mask fields in a nested object appended to log message using the Markers.appendRaw("body": <my-json-value>) method.

An example of such JSON string is

{"timestamp":"2021-10-26T22:41:29.471+02:00","message":"Response GET /examples/ ","level":"INFO", "body":[{"id":1,"password": "ABC"},{"id":2,"password":"DEF"},{"id":3,"password":"my-super-secure-password"}]"}

I've setup the logback-spring.xml file this way

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="net.logstash.logback.encoder.LogstashEncoder">

            <jsonGeneratorDecorator class="net.logstash.logback.mask.MaskingJsonGeneratorDecorator">

                  <defaultMask>****</defaultMask>

                  <path>password</path>

                  <!-- I've also tried /body/*/password, or */password -->

            </jsonGeneratorDecorator>

            <fieldNames>
                <timestamp>timestamp</timestamp>
                <message>message</message>
                <version>[ignore]</version>
                <levelValue>[ignore]</levelValue>
            </fieldNames>

        </encoder>
    </appender>
    <root level="info">
        <appender-ref ref="CONSOLE"/>
    </root>
</configuration>

The expected result would be:

{"timestamp":"2021-10-26T22:41:29.471+02:00","message":"Response GET /examples/ ","level":"INFO", "body":[{"id":1,"password": "****"},{"id":2,"password":"****"},{"id":3,"password":"****"}]"}

But I got no masking in place.

I've tried to debug the code and it seems that PathBasedFieldMasker class is not able to drill down the body object.

As a temporary solution I've build a class that masks the JSON string before logging, but it seems sub-optimal to me.

Anything I should do to make the masking take place correctly in the nested fields?


Solution

  • Masking is not designed to work with Markers.appendRaw. When using Markers.appendRaw, an application takes full responsibility for providing the exact JSON to output. In other words, logstash-logback-encoder does not process the value passed to appendRaw at all.

    You have a couple of options to get masking working...

    Option 1: Instead of using appendRaw, let logstash-logback-encoder serialize the value by passing an object or array to one of the other append* methods. This will cause logstash-logback-encoder to serialize the object/array to JSON. It is during this serialization process that masking occurs.

    Option 2: Use MaskingJsonGenerator to generate the masked value to pass to appendRaw.