Log4j 2
  1. Log4j 2
  2. LOG4J2-439

Create a LogEventPatternConverter to escape newlines and HTML special characters

    Details

    • Type: New Feature New Feature
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.0-beta9
    • Fix Version/s: 2.0-rc2
    • Component/s: Layouts
    • Labels:
      None

      Description

      To prevent log forging and HTML based attacks from viewing logs in a browser, we could add a LogEventPatternConverter that escapes newlines and HTML special characters. ESAPI has a method to do this, but it doesn't have any of the nice API features that Log4j 2 has.

      I was able to create a LogEventPatternConverter to do this. Note, this is only a proof of concept. I didn't try to exhaustively list all the special characters that might need to be replaced. I also didn't provide any configuration so we could choose to not escape HTML, for example.

      With this configuration:

      <PatternLayout pattern="%d %-5p [%t] %c %encode{%m}%n"/>
      

      And logging this message:

      LOG.warn("hi\n & <h1> there");
      

      Would result in this being logged:

      2013-10-28 16:31:21,606 WARN  [main] example.Test hi\n &amp; &lt;h1&gt; there 
      

      instead of this (which shows the potential for log forging):

      2013-10-28 16:31:21,606 WARN  [main] example.Test hi
      & <h1> there 
      

      This is roughly the code I used:

      @Plugin(name = "escape", category = "Converter")
      @ConverterKeys({ "escape" })
      public final class EscapingReplacementConverter extends LogEventPatternConverter {
      
          private final List<PatternFormatter> formatters;
      
          private EscapingReplacementConverter(final List<PatternFormatter> formatters) {
              super("escape", "escape");
              this.formatters = formatters;
          }
      
          public static EscapingReplacementConverter newInstance(final Configuration config,
                                                                 final String[] options) {
              if (options.length != 1) {
                  LOGGER.error("Incorrect number of options on escape. Expected 1, received "
                          + options.length);
                  return null;
              }
              if (options[0] == null) {
                  LOGGER.error("No pattern supplied on escape");
                  return null;
              }
              final PatternParser parser = PatternLayout.createPatternParser(config);
              final List<PatternFormatter> formatters = parser.parse(options[0]);
              return new EscapingReplacementConverter(formatters);
          }
      
          @Override
          public void format(final LogEvent event, final StringBuilder toAppendTo) {
              final StringBuilder buf = new StringBuilder();
              for (final PatternFormatter formatter : formatters) {
                  formatter.format(event, buf);
              }
              toAppendTo.append(buf.toString()
                                   .replaceAll("\\r", "\\\\r")
                                   .replaceAll("\\n", "\\\\n")
                                   .replaceAll("&", "&amp;")
                                   .replaceAll("<", "&lt;")
                                   .replaceAll(">", "&gt;"));
          }
      }
      

      If this sounds good, I would like to hear feedback and ideas on how to make this better. I will then contribute this to the project. Do you think this could this get in 2.0?

      1. EncodingPatternConverter.patch
        6 kB
        Bruce Brouwer
      2. log4j2-439-doc.patch
        2 kB
        Bruce Brouwer

        Activity

        Bruce Brouwer created issue -
        Hide
        Ralph Goers added a comment -

        This sounds reasonable to me.

        Show
        Ralph Goers added a comment - This sounds reasonable to me.
        Hide
        Bruce Brouwer added a comment -

        I've attached a patch for EncodingPatternConverter and EncodingPatternConverterTest

        Show
        Bruce Brouwer added a comment - I've attached a patch for EncodingPatternConverter and EncodingPatternConverterTest
        Bruce Brouwer made changes -
        Field Original Value New Value
        Attachment EncodingPatternConverter.patch [ 12624989 ]
        Ralph Goers made changes -
        Assignee Ralph Goers [ ralph.goers@dslextreme.com ]
        Ralph Goers made changes -
        Status Open [ 1 ] In Progress [ 3 ]
        Hide
        Ralph Goers added a comment -

        Patch applied in revision 1573211. Please verify and close.

        Show
        Ralph Goers added a comment - Patch applied in revision 1573211. Please verify and close.
        Ralph Goers made changes -
        Status In Progress [ 3 ] Resolved [ 5 ]
        Fix Version/s 2.0-rc2 [ 12326292 ]
        Resolution Fixed [ 1 ]
        Hide
        Bruce Brouwer added a comment -

        It works just as I expected. Thanks.

        Show
        Bruce Brouwer added a comment - It works just as I expected. Thanks.
        Bruce Brouwer made changes -
        Status Resolved [ 5 ] Closed [ 6 ]
        Hide
        Bruce Brouwer added a comment -

        I am only re-opening this to provide a documentation patch.

        Show
        Bruce Brouwer added a comment - I am only re-opening this to provide a documentation patch.
        Bruce Brouwer made changes -
        Resolution Fixed [ 1 ]
        Status Closed [ 6 ] Reopened [ 4 ]
        Bruce Brouwer made changes -
        Attachment log4j2-439-doc.patch [ 12634626 ]
        Hide
        Ralph Goers added a comment -

        Documentation patch applied in revision 1591549. Please verify and close.

        Show
        Ralph Goers added a comment - Documentation patch applied in revision 1591549. Please verify and close.
        Ralph Goers made changes -
        Status Reopened [ 4 ] Resolved [ 5 ]
        Resolution Fixed [ 1 ]
        Bruce Brouwer made changes -
        Status Resolved [ 5 ] Closed [ 6 ]
        Transition Time In Source Status Execution Times Last Executer Last Execution Date
        Open Open In Progress In Progress
        123d 21h 7m 1 Ralph Goers 01/Mar/14 18:45
        In Progress In Progress Resolved Resolved
        48m 34s 1 Ralph Goers 01/Mar/14 19:34
        Closed Closed Reopened Reopened
        12d 6h 27m 1 Bruce Brouwer 14/Mar/14 03:10
        Reopened Reopened Resolved Resolved
        48d 2h 57m 1 Ralph Goers 01/May/14 07:07
        Resolved Resolved Closed Closed
        3d 8h 55m 2 Bruce Brouwer 04/May/14 14:55

          People

          • Assignee:
            Ralph Goers
            Reporter:
            Bruce Brouwer
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development