OWASP ESAPI and SLF4J/Logback setup - java

I currently have a program that uses SLF4J/LoggerFactory for capturing logs and the configuration is done through logback.xml. My logs were working as expected. I was recently instructed by the Security team at my job to update a class which uses ESAPI. I updated the class and added ESAPI.properties and validation.properties to src/main/resources/esapi. In ESAPI.properties, I updated ESAPI.Logger to ESAPI.Logger=org.owasp.esapi.logging.slf4j.Slf4JLogFactory. Based on my research online and through SO, I assumed I would be able to us my logs (which is initialized as protected final static Logger log = LoggerFactory.getLogger(this.class); and used as log.info("Example")) as normal (outputs the logs to a file on a server) but the logs just output to the CL when the java program is run.

The configuration for the LogFactory indicates which Logging Framework instance org.owasp.esapi.Logger should delegate to.
From your question, it appears you are expecting a log event to follow the flow of:
MyCode -> SLF4J -> ESAPI -> Console.
In actuality, the way it's implemented is:
MyCode -> ESAPI_LOGGER -> SLF4J -> Console
The ESAPI Logger is not an implementation of the SLF4J logging contract. It will only delegate to the logger instance configured in esapi.properties. All of the references in code will need to be updated to
Logger esapiLogger = ESAPI.getLogger(myLogger_byClass_or_byName)

There are also these relevant properties in the ESAPI.properties file that you may wish to tweak:
# ESAPI Logging
# Set the application name if these logs are combined with other applications
Logger.ApplicationName=ExampleApplication
# If you use an HTML log viewer that does not properly HTML escape log data, you can set LogEncodingRequired to true
Logger.LogEncodingRequired=false
# Determines whether ESAPI should log the application name. This might be clutter in some single-server/single-app environments.
Logger.LogApplicationName=true
# Determines whether ESAPI should log the server IP and port. This might be clutter in some single-server environments.
Logger.LogServerIP=true
# Determines whether ESAPI should log the user info.
Logger.UserInfo=true
# Determines whether ESAPI should log the session id and client IP.
Logger.ClientInfo=true

I resolved my issue after reading the README.md for the current release which references the 2.2.3.0 release notes if you are using the slf4j libraries. I needed to exclude the slf4j-simple which is pulled in because it is a dependency of AntiSamy 1.6.2.

Related

mixed java logging with slf4j, log4j and java.util.logging

I'm running a web application in a Weblogic server (Im not realy familiar with ).
Via JVM args a log4j config is passed with log level DEBUG to the application.
In the log file I can also find some log entries of DEBUG level.
So far so good.
During debugging I found some calls to logger.debug() that are not in the log file.
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(ActionCtr.class);
The method call is definitely hit but nothing is written to a file.
If I do a step into during debugging I see in the logger:
org.slf4j.impl.JDK14LoggerAdapter(com.example.application.ActionCtr)
"java.util.logging.FileHandler.pattern" -> "%h/java%u.log"
And this leads to some questions for me (as I can not change the running application):
1) how could it bee that it uses the application is using a mixed up log4j and java.util.logging
2) How could I determine what is used in what classes?
3) There is no %h/java%u.log (~/java*.log) so I've tried to provide a java.util.logging conform properties file,
but this changed nothing - how an I determine where the running logger got its config from to configure it right?
1) how could it be that it uses the application is using a mixed up log4j and java.util.logging
Any of those logging frameworks could be used by the application directly or a dependent library that the application is using. It doesn't take too many dependencies to end up with a bunch of logging framework hitchhikers.
The SLF4J manual explains how that logging framework wrangles all of these other frameworks. This why you are seeing the org.slf4j.impl.JDK14LoggerAdapter.
How could I determine what is used in what classes?
Assuming you mean direct usages you can use Jdeps or Javap.
how an I determine where the running logger got its config from to configure it right?
The JConsole tool can access the JUL loggers at runtime. It will also show you all of the system properties which may include paths to logging.properties files.
If the application is pragmatically configuring the logging in an non-standard way then one option would be to use the java.security.debug using the access option. Run the application under a security manager will all or all required permissions but then enable access tracing.

Log info into the default log file of the server

My Dev machine has JBoss while production server is running tomcat8 on AWS.
How do I setup Log (java.util.loggin) to log into default log file in the default directory, for instance following are the default paths for log files for each server. (no 3rd party loggers please)
/log/tomcat8/catalina
jboss-4.0.4/server/some_server_conf/log/
In some code examples I've seen, a FileHandler("file.log") is provided but then this log exists locally within the project folder and is not accessible from outside in a production environment. I want the application to be part of the root logging system that appends the log info into default directories and into default files.
Lateral Thinking: Please advise if there's a totally different strategy for production servers.
Part of the reason is that it's easier to see the log files right from AWS by requesting last 100 lines and I'd like to append some additional meaningful information there regarding my application as it runs.
public class Service {
private static Logger logger = Logger.getLogger("myproject");
public Service() {
logger.log(Level.INFO, "abc");
}
}
The easiest solution would be to simply install a java.util.logging.ConsoleHandler on the root logger of your myproject. That would direct all of your project output to the tomcat8-stderr.YYYY-MM-DD.log.
Otherwise you can create a ServletContextListener and install a custom handler on the root logger of your project which formats and logs to the ServletContext.log methods.

Weblogic 12c with Log4j2 stops logging after stop/start

I got a pecurliar behaviour when we stop a war in Weblogic 12c and then start it again. For some reason beyond my understanding Log4j2 stops writing to the log. It creates a new logfile but no entries are written.
I have debugged and sees that Log4jServletContainerInitializer and Log4jServletContextListener gets called just like they do when installing the war. I didn't notice any differences (unfortunally thats only a test of my attention span).
So do you have any idea of what might differ between install and start in regards of Log4J2 in Weblogic 12c and perhaps where to look for errors?
Your problem:
For some reason beyond my understanding Log4j2 stops writing to the log. It creates a new logfile but no entries are written.
Root Cause Analysis:
It is actually happen for some issues.
If your configuration for log4j is not correctly done in
log4j.properties file.
If your append properties are not made true.
If you use two loggers like Log4J and JUL, which uses the same
appneder(Stdout).
If your log4j jar file is not properly set to your classpath.
Solution:
Ans-1:
In your classpath, there is a setting of library that intercepts Log4J calls and converts them to JUL calls. Then it may cause this issue. So specify correctly that which importing is actually needed. java.util.logging.Logger or org.apache.log4j.Logger
Ans-2:
Properties are case sensitive. so your file name would be same with appender. and don't forget to make the appender to true.
log4j.appender.mainAppender.File=yourLogFile.log
log4j.appender.mainAppender.Append=true
Ans-3:
for Hibernate in particular, include slf4j in order to ensure that all the loggers co-operate with it.
Ans-4:
Sometimes this problem occurs for tomcat. If tomcat security enabled, and there were several permissions missing from the policy files, then this type of issue occurs. After giving permissions, it will work fine.
What Log4J does actually?
Log4J will only print messages which are info and up, and it will print them to both console and file. You can change this behaviour by changing INFO to ALL in log4j.rootLogger. If that doesn't work, add -Dlog4j.debug=true to your JVM arguments - that will make Log4J emit debug messages about itself (to System.out), so you can see what's going on.
Credit goes to #Isaac
Resource Link:
Log4J creates log file but does not write to it
Issue with log4j log not writing to file
UPDATE for log4j2:
Thanks a lot to rgoers for pointing the issue for log4j2. I am updating.
Root cause analysis from P.O.V of wilkinsona
When a restart is triggered, DevTools runs and then clears all registered shutdown hooks. One such hook is Log4J2's DefaultShutdownCallbackRegistry. Log4jContextFactory maintains a reference to the DefaultShutdownCallbackRegistry and LogManager holds a static reference to Log4jContextFactory. Log4J2's classes are loaded by the app classloader which means that there's a single LogManager, Log4jContextFactory, and DefaultShutdownCallbackRegistry shared across restarts.
When DefaultShutdownCallbackRegistry is run as part of a restart it stops the LoggerContext and sets its own state to STOPPED. As the restart proceeds a new LoggerContext is created and an attempt is made to register a shutdown callback for it with the registry. This fails as the registry's state is still STOPPED.
Solution:
Wilkinsona offered a hack method to solve the issue. That is given below. Try to cope with it.
Clearing out the callbacks in the registry before the Restarter runs the JVM's shutdown hooks is better. It prevents the exception from occurring, and logging continues to work after a restart.
private void prepareLog4J2ForRestart() throws Exception {
if (ClassUtils.isPresent("org.apache.logging.log4j.LogManager",
getClass().getClassLoader())) {
LoggerContextFactory factory = LogManager.getFactory();
Field field = ReflectionUtils.findField(factory.getClass(),
"shutdownCallbackRegistry");
ReflectionUtils.makeAccessible(field);
ShutdownCallbackRegistry shutdownCallbackRegistry = (ShutdownCallbackRegistry) ReflectionUtils
.getField(field, factory);
Field hooksField = ReflectionUtils
.findField(shutdownCallbackRegistry.getClass(), "hooks");
ReflectionUtils.makeAccessible(hooksField);
#SuppressWarnings("unchecked")
Collection<Cancellable> state = (Collection<Cancellable>) ReflectionUtils
.getField(hooksField, shutdownCallbackRegistry);
state.clear();
}
}
Resource Link:
Log4j 2.4 breaks rc1 devtools
Call context.close() rather than shutdown hook in DevTools restart
UPDATE2:
What kind of listener to add to my JEE application, to get the
expected behaviour?
For writing a listener, you can follow the tutorials
ServletContextListener Example
Writing a Listener Class
Servlet Listener Example – ServletContextListener,
HttpSessionListener and ServletRequestListener

Is it possible to get the root log level of Jboss Server, if custom loggers are used instead of logging service provided by the Server?

Following are the requirements,
multiple modules deployed on JBoss AS 7 with individual logging configuration using logback.xml.
all of them request exclusion of default logging-service provided by the Server, using jboss-deployment-structure.xml.
Following are observation,
log.debug statements get printed as INFO on Server log(server.log)
it's because root level of custom-logger(logback.xml) is set to DEBUG
Now questions,
How can I make, DEBUG statements generated by custom logging statement gets printed with appropriate log level?
Conversely, is it possible to get log level of Server without using it's logging service?
In other words, is it possible to achieve uniform log-level configuration across multiple modules that use custom-loggers?

Logging issue with Spring (core & jdbc not MVC)

My application is using Spring to handle the interaction with database (Sql Server)
And commons-logging-1.1.1.jar, log4j-1.2.17.jar, slf4j-api-1.6.3.jar and slf4j-log4j12-1.7.6.jar are put into build path for the logging framework of the application.
The last two logging jar (slf4j-api and slf4j-log4j12) are for another component inside the application to use log4j.
Here is my questions:
When Spring-Jdbc runtime excecption happens, the exception is only showed in the console of eclipse with the font color red. The exception is NOT logged into the log file. But the normal log (like log.info(...)) are all in the log file. Why can't the run-time exception be in the log file and how to solve this problem.
When I use SimpleJdbcCall to call the stored procedure with parameters in MapSqlParameterSource, the following log shows up:
14:43:30 [INFO ] Added default SqlReturnUpdateCount parameter named #update-count-1
14:43:30 [INFO ] Added default SqlReturnUpdateCount parameter named #update-count-1
......
It's really annoying because the number of this message is so large. I want to turn off this particular log message without affecting another logging with the same level (INFO)
And my log4j.xml is fine I think because the logging are basically fine except the above issues.
Spring is using commons-logging internally that's why you can see the messages in your eclipse console. To redirect commons-logging to slf4j/log4j you need to remove commons-logging-1.1.1.jar from your classpath and add jcl-over-slf4j.jar from your slf4j version. To get rid of the dublicate red eclipse messages (jul and jcl) you can set the logging level in logging.properties for the console handler to warning:
java.util.logging.ConsoleHandler.level = WARNING
Second issue was solved here.

Categories

Resources