49

I configure my Log4j with an XML file. Where should I add the formatMsgNoLookups=true?

<?xml version="1.0" encoding="UTF-8"?>
<!--  Upload files compare config -->
<configuration status="OFF">
  <appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss} %p - %msg%n"/>
    </Console>

    <!-- http://logging.apache.org/log4j/2.x/manual/appenders.html#RollingFileAppender -->
    <RollingFile name="File" fileName="logs/MyLogFile.log"
                          filePattern="logs/MyLogFile-%d{yyyy-MM-dd}.log"
                 ignoreExceptions="false">
      <PatternLayout>
        <Pattern>%d %p %c{1.} %m%n</Pattern>
      </PatternLayout>
    </RollingFile>
  </appenders>
  <Loggers>
    <Root level="INFO">
      <AppenderRef ref="File"/>
      <AppenderRef ref="Console"/>
    </Root>
  </Loggers>
</configuration>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ben
  • 2,771
  • 6
  • 33
  • 45
  • 3
    One way is using System Property - see [java -Dlog4j2.formatMsgNoLookups=true ...](https://spring.io/blog/2021/12/10/log4j2-vulnerability-and-spring-boot) or other suggestions are to delete `JndiLookup.class` – DuncG Dec 11 '21 at 14:10

7 Answers7

43

CVE-2021-44228 Log4Shell Vulnerability

If you can, upgrade to Log4j2 + Java versions as recommended by the security details on the Apache logging site. This site has changed since my original post; always follow recommended guidelines from the Apache website.

The Apache site previously suggested some workarounds for the JNDI lookup vulnerability reported against earlier releases of Log4j2.

IMO: This is such a serious vulnerability, you shouldn't contemplate these workarounds, and by the time you read this they may not help anyway. Upgrade Log4j JAR files and see the note below on places to check.

  1. Set system property log4j2.formatMsgNoLookups when you launch the VM, passing as java -Dlog4j2.formatMsgNoLookups=true ... .
  2. Set environment variable LOG4J_FORMAT_MSG_NO_LOOKUPS to true.
  3. For releases from 2.0-beta9 to 2.10.0, the mitigation is to remove the org/apache/logging/log4j/core/lookup/JndiLookup.class from the classpath - see log4j-core-*.jar.
  4. replace format pattern %m by %m{nolookups} for some versions

I could not find LOG4J_FORMAT_MSG_NO_LOOKUPS when running a grep on the Java source code for 2.14.0, so it’s not clear if this helps at all.

Certain JDK releases mitigate the risks: JDK greater than 6u211, 7u201, 8u191, and 11.0.1 are not affected due to defaults applied to LDAP lookups. Upgrade where possible.

Some places to check for Log4j use

Check which versions of Java you use are recent enough:

java -version

Scan your application release structures, app servers, development environments for possible old versions of Log4j:

find yourReleaseDir -type f -name log4j\*jar

If you are unsure about which Log4j version you have open the JAR file in a ZIP tool and view META-INF\MANIFEST.MF - there may a line with details of the version:

 Log4jReleaseVersion: A.B.C

View the running processes on each release machine to see if there are any open file handles to Log4j JAR files:

lsof | grep log4j

Also scan machines to verify the Java VM are versions you expect. This may spot more applications to work on:

ps -ef | egrep "(java|jdk)"    #OR: | grep -v grep

Scan EAR and WAR archives on application servers to verify there aren’t any embedded Log4j JAR files inside a container archive. You can do this with find and unzip commands, or try the ShowClassVersions class I wrote to detect Java compiler versions in this answer. This would print out names of JAR files inside WAR and EAR files:

java ShowClassVersions.java app_server_dir |grep log4j
app_server_dir/somewebapp.war => WEB-INF/lib/log4j2-core.jar
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
DuncG
  • 12,137
  • 2
  • 21
  • 33
  • 1
    OP is asking, and I too am wondering, if it is possible to set the `formatMsgNoLookups=true` somewhere in the log4j2.xml file. If so, where and how? – Andy Lester Dec 13 '21 at 16:06
  • Yes I've mentioned it briefly `%m{nolookups}` above and see answer by @Mj.B (note: I'm not able to test as am not affected by this awful log4j problem) – DuncG Dec 13 '21 at 16:09
  • I'd add to this answer that if you're using `Jib`, then you can check which library versions you have using `docker run --rm -it --entrypoint grep log4j app/libs -r` – dan Dec 13 '21 at 19:08
  • How about if an application uses the Windows Registry to enter parameters as Strings? Can a line item be added here for what to name the string and what its value should be, for example? – TylerH Dec 14 '21 at 19:26
  • Only first workaround applies to command line parameters, adding `-Dlog4j2.formatMsgNoLookups=true` to a java command before the classname should trigger that workaround IF you are using the right log4j2 versions. But why risk having the jar on your machine or someone adding a new dependency / app which does not make use of the workaround? – DuncG Dec 14 '21 at 19:51
  • As per today's update from Apache, setting the system property log4j2.formatMsgNoLookups to true do NOT mitigate this specific vulnerability. https://logging.apache.org/log4j/2.x/security.html – SuRa Dec 16 '21 at 18:55
19

As DuncG commented, the option to disable lookups for Log4j is not a configuration option but a system property

log4j2.formatMsgNoLookups

Depending on your environment (Spring, stand-alone executable, Tomcat web application,…) the way system properties are set may vary. The simplest possibility for starting a Java process from a JAR file would be to add

-Dlog4j2.formatMsgNoLookups=true

to your command line:

java -Dlog4j2.formatMsgNoLookups=true -jar myapp.jar
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
dpr
  • 10,591
  • 3
  • 41
  • 71
  • 1
    OP is asking, and I too am wondering, if it is possible to set the `formatMsgNoLookups=true` somewhere in the log4j2.xml file. If so, where and how? – Andy Lester Dec 13 '21 at 16:06
  • 2
    @AndyLester the option to disable lookups in the log4j.xml configuration would be use `%m{nolookups}` instead of just `%m` in every pattern. As there is no option to disable lookups for all patterns with a single switch this option is error prone (a pattern might be missed or added later without this parameter). Thus this is not the recommended approach. – dpr Dec 13 '21 at 21:09
  • So, the answer to "if it is possible to set the `formatMsgNoLookups=true` somewhere in the log4j2.xml file" is "no, it's not." – Andy Lester Dec 13 '21 at 22:14
  • 3
    @AndyLester exactly. I thought the sentence "the option to disable lookups for log4j is not a configuration option" would state exactly this. – dpr Dec 13 '21 at 22:44
  • I guess I don't understand the difference between "configuration option" and "system property" as to how and where it would get set. I guess you're saying log4j.xml can only set configuration options and not system properties. – Andy Lester Dec 13 '21 at 22:54
  • 2
    Since Log4j 2.x reads properties from at least three sources (cf. [documentation](https://logging.apache.org/log4j/2.x/manual/configuration.html#SystemProperties)), it is also possible to put the setting into a `log4j2.component.properties` file in the application's classpath. – Piotr P. Karwasz Dec 14 '21 at 04:13
7

You can do this: %m{nolookups} in the layout.

{nolookups} is how you set the property log4j2.formatMsgNoLookups=true within the configuration XML content.

Quoting from the Log4j source:

public static final boolean FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS = PropertiesUtil.getProperties().getBooleanProperty("log4j2.formatMsgNoLookups", false);

and its javadoc:

LOG4J2-2109 if true, MessagePatternConverter will always operate as though

%m{nolookups}

is configured.

Since:

2.10

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mj.B
  • 191
  • 9
3

Add the delimiter -Dlog4j2.formatMsgNoLookups=true under the export catalina_opts or export java_options.

JW Geertsma
  • 857
  • 3
  • 13
  • 19
shivrajg
  • 31
  • 1
2

Remember to always check for the latest information from the resources listed below.

CVE-2021-45105... 2.16.0 and 2.12.2 are no longer valid remediations! The current fixing versions are 2.17.0 (Java 8) and 2.12.3 (Java 7). All other Java versions have to take the stop gap approach (removing/deleting JndiLookup.class file from the log4j-core JAR.


The environment variable option is no longer considered a valid remediation or mitigation. It will technically slightly reduce the exposure of the vulnerability, but it won't actually fix anything. I outline remediation info below.


Remediation:

CVE-2021-45046 ... CVE-2021-44228 ... CVE-2021-45105

  • Follow the guidance in those resources... it may change, but

As of 2021-12-18

It's basically

  • Remove log4j-core JAR files if possible
    • From both running machines for an immediate fix and
    • in your source code / source code management files to prevent future builds / releases / deployments from overwriting the change
  • If that is not possible (due to a dependency), upgrade them
    • If you are running Java 8, then you can upgrade to Log4j 2.17.0+
    • If you are running Java 7, then you can upgrade to Log4j 2.12.3
    • If you are running an older version of Java, then you need to upgrade to the newest version of Java and then use the newest version of Log4J
    • Again, these changes have to happen both on running machine and in code
  • If neither of those are possible for some reason... then there is the non-remediation stop gap of removing the JndiLookup.class file from the log4j-core JAR files.
    • There is a one-liner for the stop gap option on Linux using the zip command that comes packaged with most Linux distributions by default.
      • zip -q -d "$LOG4J_JAR_PATH" org/apache/logging/log4j/core/lookup/JndiLookup.class
    • At time of writing, most of the guides online for the stop gap option on Windows say to do the following (again... assuming you can't do one of the remove JAR or upgrade options above):
      • Install something like 7-Zip
      • Locate all of your log4j-core JAR files and for each one do the following...
      • Rename the JAR to change the extension to .zip
      • Use 7-Zip to unzip the JAR file (which now has a .zip extension)
      • Locate and remove the JndiLookup.class file from the unzipped folder
        • The path is \\path\\to\\unzippedFolder\\org\\apache\\logging\\log4j\\core\\lookup\\JndiLookup.class
      • Delete the old JAR file (which now has an extension of .zip)
      • Use 7-Zip to re-zip the folder
      • Rename the new .zip folder to change the extension to .jar
    • There are also some options to use PowerShell

This is fine if you only have one or two JAR files to deal with and you don't mind installing 7-Zip or you have PowerShell available to do it. However, if you have lots of JAR files, or if you don't want to install 7-Zip and don't have access to PowerShell, I created an open-source VBScript script (.vbs) that will do it for you without needing to install any additional software. Windowslog4jClassRemover

Read the README and the release notes - Release: The light is really easy to read & follow now CrazyKidJack/Windowslog4jClassRemover

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • I think my answer is clear: "you shouldn't contemplate these workarounds" especially as one isn't even matched by the source code. – DuncG Dec 17 '21 at 11:16
  • @DuncG version 2.15 is no longer a valid remediation. Please update your answer to 2.16.0 for Java 8 and 2.12.2 for Java 7. Since remediation advice changes frequently, I would suggest you also include a link to a 3rd party security info place. If you make those modifications, I'm happy to remove my "warning" message. I have also updated my answer to more accurately reflect the problem with your answer – Jackson Pfeffer Dec 17 '21 at 15:37
  • I've amended, I hope that helps. – DuncG Dec 17 '21 at 15:46
  • @DuncG Awesome :) Thanks! I have ammeded my answer as well – Jackson Pfeffer Dec 19 '21 at 07:37
  • Hi! I dont familar with that library, but I think we can just add in source code of main program file with path: \\path\\to\\unzippedFolder\\org\\apache\\logging\\log4j\\core\\lookup\\JndiLookup.java . And just stub bad code in that file. JVM will search class in sources first. It will more strict than any params is`t it? – andrejs82 Dec 20 '21 at 11:26
  • @andrejs82 I'm not 100% sure I understand what you are saying. #1 You are correct that changing "params" will not fix this vulnerability #2 If you are asking whether or not you can fix this vulnerability in code, the answer is yes. You need to force your code/build to use the fixed version of Log4J. If you have further questions, please ask! – Jackson Pfeffer Dec 20 '21 at 15:42
0

There is a lot of confusion regarding the variable to use, log4j2.formatMsgNoLookups, log4j.formatMsgNoLookups, etc. Keep in mind that as indicated in PropertySource.java,

/ **
* Converts a property name string into a list of tokens. This will strip a prefix of {@code log4j},
* {@code log4j2}, {@code Log4j}, or {@code org.apache.logging.log4j}, along with separators of
* dash {@code -}, dot {@code.}, underscore {@code _}, and slash {@code /}. Tokens can also be separated
* by camel case conventions without needing a separator character in between.
*
* @param value property name
* @return the property broken into lower case tokens
* /

You can use different values ​​for the variable, as you can check with this test code (unfortunately, you must indicate the property of the system in a static block, so to test the different options, you must comment or uncomment the different lines of the test).

package org.apache.logging.log4j.core.pattern;

import org.apache.logging.log4j.core.util.Constants;
import org.junit.Test;

import static org.junit.Assert.assertTrue;

/ **
 *
 * /

public class Log4jParameterTest {
    static {
        // Test Ok. All working
// System.setProperty ("log4j2.formatMsgNoLookups", "true");
// System.setProperty ("log4j.formatMsgNoLookups", "true");
// System.setProperty ("Log4j.formatMsgNoLookups", "true");
// System.setProperty ("org.apache.logging.log4j.formatMsgNoLookups", "true");
// System.setProperty ("log4j2-formatMsgNoLookups", "true");
// System.setProperty ("log4j2_formatMsgNoLookups", "true");
        System.setProperty ("log4j2 / formatMsgNoLookups", "true");
        // Test KO. All fail
// System.setProperty ("log5j2.formatMsgNoLookups", "true");
// System.setProperty ("log5j2-formatMsgNoLookups", "true");
    }
    @Test
    public void testLookupEnabledByDefault () {
        assertTrue ("Lookups deactivated", Constants.FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS);

    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Cesar
  • 1
  • 1
-1

To whom use log4j-xml-config-file:

  1. Replace %m by %m{nolookups} in the PatternLayout
  2. Add system property log4j.formatMsgNoLookups = true: System.setProperty("log4j2.formatMsgNoLookups", "true");
Al3xC
  • 194
  • 2
  • 7
  • 1
    What is "log4j-xml-config-file"? A file? A package? Something else? – Peter Mortensen Jan 02 '22 at 15:55
  • @PeterMortensen: it should be the log4j2.xml or log4j.xml configuration file. I just want to mention the "Log4j XML configuration file" as the thread title – Al3xC Jan 19 '22 at 03:53