ESAPI - Getting NoClassDefFoundError (LoggerFactory) with banned dependency
Asked Answered
D

5

13

I am using ESAPI to encode string value to resolve cross site scripting issue as shown below (code snippet).

String encodedString = ESAPI.encoder().encodeForHTML(value);

Exception Trace

org.owasp.esapi.errors.ConfigurationException: java.lang.reflect.InvocationTargetException Encoder class (org.owasp.esapi.reference.DefaultEncoder) CTOR threw exception.
    at org.owasp.esapi.util.ObjFactory.make(ObjFactory.java:129)
    at org.owasp.esapi.ESAPI.encoder(ESAPI.java:99)
<bold>Caused by: java.lang.NoClassDefFoundError: org/apache/log4j/spi/LoggerFactory</bold>
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:190)
    at org.owasp.esapi.util.ObjFactory.make(ObjFactory.java:74)
    at org.owasp.esapi.ESAPI.logFactory(ESAPI.java:137)
    at org.owasp.esapi.ESAPI.getLogger(ESAPI.java:154)
    at org.owasp.esapi.reference.DefaultEncoder.<init>(DefaultEncoder.java:75)
    at org.owasp.esapi.reference.DefaultEncoder.getInstance(DefaultEncoder.java:59)
    ... 71 more
Caused by: java.lang.ClassNotFoundException: org.apache.log4j.spi.LoggerFactory
    at weblogic.utils.classloaders.GenericClassLoader.findLocalClass(GenericClassLoader.java:297)
    at weblogic.utils.classloaders.GenericClassLoader.findClass(GenericClassLoader.java:270)
    at weblogic.utils.classloaders.ChangeAwareClassLoader.findClass(ChangeAwareClassLoader.java:64)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)

Maven repository pom.xml

<dependency>
    <groupId>org.owasp.esapi</groupId>
    <artifactId>esapi</artifactId>
    <version>${org.owasp.esapi.version}</version>
    <exclusions>
        <exclusion>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
        </exclusion>
        <exclusion>
            <groupId>xercesImpl</groupId>
            <artifactId>xercesImpl</artifactId>
        </exclusion>
        <exclusion>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
        </exclusion>
        <exclusion>
            <groupId>xml-apis</groupId>
            <artifactId>xml-apis</artifactId>
        </exclusion>
        <exclusion>
            <groupId>commons-digester</groupId>
            <artifactId>commons-digester</artifactId>
        </exclusion>
        <exclusion>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.owasp.antisamy</groupId>
            <artifactId>antisamy</artifactId>
        </exclusion>
        <exclusion>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </exclusion>
    </exclusions>
</dependency>

If I don't exclude log4j then it will throw dependency convergence error because log4j is declared in maven banned dependency as shown below

<executions>
    <execution>
        <id>enforce</id>
        <configuration>
            <rules>
                <requireJavaVersion>
                    <version>${java.version}</version>
                </requireJavaVersion>
                <requireMavenVersion>
                    <version>3.0</version>
                </requireMavenVersion>
                <DependencyConvergence />
                <bannedDependencies>
                    <excludes>
                        <!-- This should not exist as it will force SLF4J calls to be 
                            delegated to log4j -->
                        <exclude>org.slf4j:slf4j-log4j12</exclude>
                        <!-- This should not exist as it will force SLF4J calls to be 
                            delegated to jul -->
                        <exclude>org.slf4j:slf4j-jdk14</exclude>
                        <!-- Ensure only the slf4j binding for logback is on the classpath -->
                        <exclude>log4j:log4j</exclude>
                        <!-- As recommended from the slf4j guide, exclude commons-logging -->
                        <exclude>commons-logging:commons-logging</exclude>
                    </excludes>                                     
                </bannedDependencies>
            </rules>
        </configuration>
        <goals>
            <goal>enforce</goal>
        </goals>
    </execution>
</executions>

Help in this regard would be appreciated. Please let me know if you need any more details. Thanks in advance!

Daggerboard answered 15/12, 2015 at 16:58 Comment(0)
K
16

ESAPI does not support SLF4J, even though that in turn supports log4j. Your logging choices for ESAPI are either log4j or java.util.logging, controlled via the ESAPI.logger property in ESAPI.properties. If you decide to use log4j (i.e., ESAPI.Logger=org.owasp.esapi.reference.Log4JLogFactory), then you need the log4j.jar and either a log4j.xml or log4j.properties in your classpath, depending on which version of log4j you are using. Alternately, you can use java.util.logging by setting ESAPI.Logger=org.owasp.esapi.reference.JavaLogFactory in your ESAPI.properties file.

I see you appear to be doing this for Wells Fargo. If you have further questions, look up "Kevin W. Wall" in Teamworks and send me an email as I am part of the Secure Code Review team there as well as project lead for ESAPI, so given more context, I may be able to suggest other possibilities.

-kevin

Katowice answered 3/1, 2016 at 1:38 Comment(2)
Thanks Kevin its working now. I changed ESAPI.Logger=org.owasp.esapi.reference.JavaLogFactoryDaggerboard
This is no longer true. See @Carlo's answer.Jacklynjackman
T
22

I upgraded to the latest version 2.2.1.1 and I needed to add two additional properties (in addition to the one that @Carlo pointed out) in ESAPI.properties:

ESAPI.Logger=org.owasp.esapi.logging.slf4j.Slf4JLogFactory
Logger.UserInfo=false
Logger.ClientInfo=false
Theodicy answered 25/9, 2020 at 20:28 Comment(1)
It helped, although in my case we're using Log4j2, and I had to use org.owasp.esapi.logging.log4j.Log4JLogFactory which was moved to this package from org.owasp.esapi.reference.Log4JLogFactory.Trichromat
K
16

ESAPI does not support SLF4J, even though that in turn supports log4j. Your logging choices for ESAPI are either log4j or java.util.logging, controlled via the ESAPI.logger property in ESAPI.properties. If you decide to use log4j (i.e., ESAPI.Logger=org.owasp.esapi.reference.Log4JLogFactory), then you need the log4j.jar and either a log4j.xml or log4j.properties in your classpath, depending on which version of log4j you are using. Alternately, you can use java.util.logging by setting ESAPI.Logger=org.owasp.esapi.reference.JavaLogFactory in your ESAPI.properties file.

I see you appear to be doing this for Wells Fargo. If you have further questions, look up "Kevin W. Wall" in Teamworks and send me an email as I am part of the Secure Code Review team there as well as project lead for ESAPI, so given more context, I may be able to suggest other possibilities.

-kevin

Katowice answered 3/1, 2016 at 1:38 Comment(2)
Thanks Kevin its working now. I changed ESAPI.Logger=org.owasp.esapi.reference.JavaLogFactoryDaggerboard
This is no longer true. See @Carlo's answer.Jacklynjackman
V
12

Just an update: the support for SLF4J has been added, so if you are using ESAPI version 2.2.0.0 you may use it by setting the ESAPI.Logger property to the value org.owasp.esapi.logging.slf4j.Slf4JLogFactory

Vinna answered 10/2, 2020 at 7:56 Comment(0)
S
4

If your SpringBoot project does not have ESAPI.properties, then add file with name ESAPI.properties in src/main/resource folder and add following lines to it.

ESAPI.Logger=org.owasp.esapi.logging.slf4j.Slf4JLogFactory
ESAPI.LogEncodingRequired=false

Also check maven referenced libraries and check version of esapi, it should be esapi-2.2.0.0 or esapi-2.2.1.1(basically you should be using these esapi versions)

Note: You can add more properties based on errors you get when you run your application.

Synectics answered 5/3, 2021 at 20:49 Comment(2)
If you have a some reference on how can I integrate a simple springboot with esapi, I would really appreciate the help. I am kind of lost in somewhereWheat
will give some pointers in a day.Synectics
M
-1

For few versions of ESAPI, post 2.2.0.0, they've changed the **LogFactory implementation, we can open the ESAPI jar from classpath and find the specific LogFactory class they are using,

package details for esapi-2.5.3.1.jar in my case,

org.owasp.esapi.logging.slf4j.Slf4JLogFactory

Add that fully qualified classname in ESAPI.properties file with additional properties as,

ESAPI.Logger=org.owasp.esapi.logging.slf4j.Slf4JLogFactory
Logger.UserInfo=false
Logger.ClientInfo=false
Melyndamem answered 15/3 at 13:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.