Recipe Name:
SLF4J Logging: Print Exceptions using SLF4J instead
Description:
Standardise on SLF4J by replacing this call
Level:
marked_information
Language:
- java
Tags:
- security
- SLF4J
- framework specific
- logging
Documentation
Throwable.printStacktrace
leaks valuable program structure information.
Printing a stack trace gives valuable information about the application's internals, including library/framework names and versions, to an attacker. The method printStaceTrace
of java.lang.Throwable
will result in valuable program information being printed on standard error. Instead, an appropriate logger, such as SLF4J, should be used.
public void printMessages(Throwable e) { e.printStackTrace(); e.printStackTrace(System.err); e.printStackTrace(System.out); }After
private final static org.slf4j.Logger LOGGER = org.slf4j.LoggerFactory.getLogger(LoggingExample.class); public void printMessages(Throwable e) { LOGGER.error("", e); LOGGER.error("", e); LOGGER.error("", e); }
Recipe
id: scw:logging:slf4j:printstacktrace version: 10 metadata: name: 'SLF4J Logging: Print Exceptions using SLF4J instead' shortDescription: Standardise on SLF4J by replacing this call level: marked_information language: java scwCategory: infoexposure:debuginfo cweCategory: 200 enabled: true comment: "" descriptionFile: Java/Logging/descriptions/ThrowablePrintStacktraceLeaksInfo.html tags: security;SLF4J;framework specific;logging search: methodcall: in: typeDeclaration: anyOf: - with: child: field: name: logger type: org.slf4j.Logger - without: child: field: name: logger type: reference: not: org.slf4j.Logger checkInheritance: true name: printStackTrace type: java.lang.Throwable availableFixes: - name: '[OPTIONAL] Replace with SLF4J debug function' actions: - rewrite: to: logger.debug({{{qualifier}}}.toString(), {{{ qualifier }}}) target: self - addField: field: private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger({{{ containingClass.containingClass.name }}}.class); target: parentClass - name: ' [RECOMMENDED] Replace with SLF4J error function' actions: - rewrite: to: logger.error({{{qualifier}}}.toString(), {{{ qualifier }}}) target: self - addField: field: private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger({{{ containingClass.containingClass.name }}}.class); target: parentClass - name: '[OPTIONAL] Replace with SLF4J info function' actions: - rewrite: to: logger.info({{{qualifier}}}.toString(), {{{ qualifier }}}) target: self - addField: field: private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger({{{ containingClass.containingClass.name }}}.class); target: parentClass - name: '[OPTIONAL] Replace with SLF4J warn function' actions: - rewrite: to: logger.warn({{{qualifier}}}.toString(), {{{ qualifier }}}) target: self - addField: field: private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger({{{ containingClass.containingClass.name }}}.class); target: parentClass - name: '[OPTIONAL] Replace with SLF4J trace function' actions: - rewrite: to: logger.trace({{{qualifier}}}.toString(), {{{ qualifier }}}) target: self - addField: field: private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger({{{ containingClass.containingClass.name }}}.class); target: parentClass