Securing Apache CXF message logs

Over the last weeks I thought a lot about adjusting rewriting log messages to filter out ssensitive information which should not go into a logfile or anywhere on a harddisk. As I’m using log4j the best solution I came up with was implementing log4j’s RewritePolicy and using regular expressions to filter out any information which should not go on a file. When the application and logging configuration starts log4j prints a warning which can be ignored. The policy will still be created.

log4j:WARN Continuable parsing error 9 and column 80
log4j:WARN Elementtyp "rewritePolicy" muss deklariert werden.
log4j:WARN Continuable parsing error 11 and column 13
log4j:WARN Content des Elementtyps "appender" muss "(errorHandler?,param*,rollingPolicy?,triggeringPolicy?,connectionSource?,layout?,filter*,appender-ref*)" entsprechen.

Now lets use it with Apache CXF and filter the BASIC Authentication HTTP header on a message log. The policy gets configured by wrapping the main appender with a RewriteAppender with the policy as a configuration element in XML.

<appender name="console" class="org.apache.log4j.rewrite.RewriteAppender">
  <rewritePolicy class="com.example.logging.SecurityRewritePolicy" />
  <appender-ref ref="consoleTarget" />
</appender>
<appender name="consoleTarget" class="org.apache.log4j.ConsoleAppender">
  <param name="encoding" value="UTF-8"/>
  <layout class="org.apache.log4j.PatternLayout">
    <param name="ConversionPattern" value="%d %x %p %t %c: %m%n"/>
  </layout>
</appender>

The next is to implement the policy.

public class SecurityRewritePolicy implements RewritePolicy {

  /**
   * Matches BASIC AUTH Http-Headers.
   */
  private static final Pattern BASIC_AUTH_PATTERN = Pattern.compile("Authorization=\\[Basic ([a-zA-Z0-9+/=]+)\\]");

  @Override
  public LoggingEvent rewrite(LoggingEvent source) {
    String message = source.getRenderedMessage();
    StringBuilder messageBuilder = new StringBuilder(message);

    secureString(BASIC_AUTH_PATTERN, messageBuilder, message);

    LoggingEvent securedEvent = new LoggingEvent(source.getFQNOfLoggerClass(), source.getLogger(),
      source.getTimeStamp(), source.getLevel(), messageBuilder.toString(), source.getThreadName(),
      source.getThrowableInformation(), source.getNDC(), source.getLocationInformation(),
      source.getProperties());
    return securedEvent;
  }

  private void secureString(final Pattern pattern, final StringBuilder messageBuilder, final String message) {
    Matcher matcher = pattern.matcher(message);
    while (matcher.find()) {
      int start = matcher.start(1);
      int end = matcher.end(1);
      String escapedString = StringUtils.repeat("X", end - start);
      messageBuilder.replace(start, end, escapedString);
    }
  }

}

This implementation uses a regular expression to replace the BASIC Authentication HTTP header in Apache CXF log messages. You can add as many regular expressions as you want. Just keep in mind that every matching costs time.

Schlagwörter: , ,

Schreibe einen Kommentar

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: