Skip to content
August Detlefsen edited this page Jun 27, 2017 · 4 revisions

In addition to the standard data captured by most loggers like timestamp and severity, the OWASP Security Logging API allows applications to easily log the additional data that is required to conduct forensics on a security event:

  • Who? Account name and session identifier
  • What? Affected system or component
  • Where? IP address of attacker

Adding this extra data to log events is done through the use of Mapped Diagnostic Contexts (MDCs). MDCs allow developers to place information into a separate data structure that is maintained on a per-thread basis. This diagnostic information can be subsequently retrieved by certain logging components, such as filters and layouts. For more information about MDCs, please see the Logback Manual.

The OWASP Logging API provides a J2EE Filter that places security-specific logging information in the diagnostic context for each request:

  • IP Address of requestor
  • Session ID (hashed)
  • Component name
  • Username
  • Other information gathered through filter plugins

The J2EE filter is configured by adding the following filter definition to web.xml:

<filter>
    <filter-name>LoggingFilter</filter-name>
    <filter-class>org.owasp.security.logging.mdc.MDCFilter</filter-class>
    <init-param>
        <!-- component name is a free-from text value -->
        <param-name>component</param-name>
        <param-value>myapplication-component</param-value>
    </init-param>
    <!-- Plugins are specified by name and class -->
    <init-param>
        <param-name>ipAddress</param-name>
        <param-value>org.owasp.security.logging.mdc.ForwardedIPAddressPlugin</param-value>
    </init-param>
    <init-param>
        <param-name>username</param-name>
        <param-value>org.owasp.security.logging.mdc.UsernamePlugin</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>LoggingFilter</filter-name>
    <url-pattern>/*</url-pattern> 
</filter-mapping>

Once the filter is in operation, each request is tagged with contextual information as soon as it begins to be processed by the server. The contextual information can be accessed in the log layout by markers in the format %{markerName}. For example, the following layout adds the username and IP address to the standard log output:

<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
    <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %marker %logger{36} - %X{username}@%X{ipAddress} - %msg%n</pattern>
</encoder> 

MDC Plugins

The MDC Filter can be customized to log different types of information with plugins. Plugins must conform to the org.owasp.security.logging.mdc.IPlugin interface:

public interface IPlugin {

    /**
     * Initialize the plugin and load any required resources.
     */
    public void init(FilterConfig config);

    /**
     * Execute the plugin's action and place information into the diagnostic context.
     * 
     * @param request 
     */
    public void execute(HttpServletRequest request);
}

The execute() method of each plugin is called for every filtered HTTP request and adds information to the diagnostic context. For example, the following execute() method adds the requestor's IP address to the diagnostic context, based on the X-FORWARDED-FOR header added by an intervening load balancer:

public void execute(HttpServletRequest request) {
    String ipAddress = request.getHeader("X-FORWARDED-FOR");
    if (ipAddress == null) {
        ipAddress = request.getRemoteAddr();
    }
    MDC.put(MDCFilter.IPADDRESS, ipAddress);
}