1、簡介
針對Java的日志系統有多種,本文主要描述如何通過修改配置文件來解決logback和log4j的日志偽造問題。
2、logback
2.1、系統提供的解決方案
在logback.xml
中配置編碼器自動轉義特殊字符:
復制
<configuration><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %replace(%msg){'[\r\n]', '\\n'}%n</pattern></encoder></appender><root level="INFO"><appender-ref ref="CONSOLE" /></root>
</configuration>
2.2、自定義的解決方案
對于Logback,可以創建自定義轉換器:
public class SanitizingConverter extends ClassicConverter {@Overridepublic String convert(ILoggingEvent event) {return event.getFormattedMessage().replace("\n", "\\n").replace("\r", "\\r");}
}
再在配置文件中配置自定義的轉換器:
<configuration><conversionRule conversionWord="sanitizedMsg" converterClass="com.example.SanitizingConverter"/><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%d %sanitizedMsg%n</pattern></encoder></appender>
</configuration>
?
2、log4J
2.1 使用過濾器(Filter)
創建自定義Filter:
import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.LoggingEvent;public class LogForgeFilter extends Filter {@Overridepublic int decide(LoggingEvent event) {String message = event.getRenderedMessage();if (message != null && (message.contains("\n") || message.contains("\r"))) {return Filter.DENY; // 拒絕包含換行符的日志}return Filter.NEUTRAL;}
}
然后在配置中添加:
log4j.appender.CONSOLE.filter.1=com.yourpackage.LogForgeFilter
?這種方法由于在異常情況下,會不記錄日志,就會導致有些異常的日志被過濾調了,不利于后期的攻擊的調查。建議還是使用其它方案,把所有的日志都記錄下來。
2.2、Log4J 1.x
2.2.1、系統提供的解決方案
在log4j.properties
中添加或修改以下配置:
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
log4j.appender.CONSOLE.layout.replaceNewlines=true
2.2.2、自定義的解決方案
-
首先創建一個自定義的Layout類:
import org.apache.log4j.PatternLayout;
import org.apache.log4j.spi.LoggingEvent;public class SanitizingPatternLayout extends PatternLayout {@Overridepublic String format(LoggingEvent event) {String message = super.format(event);// 替換換行符和回車符return message.replace("\n", "\\n").replace("\r", "\\r");}
}
? ?2. 在log4j.properties
中使用這個自定義Layout:?
log4j.appender.CONSOLE.layout=com.example.SanitizingPatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
2.3、Log4J 2
2.3.1、系統提供的解決方案
在log4j2.xml
中使用encode{}
或替換模式:
<Configuration><Appenders><Console name="Console" target="SYSTEM_OUT"><PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %encode{%msg}{CRLF}%n"/></Console></Appenders><Loggers><Root level="info"><AppenderRef ref="Console"/></Root></Loggers>
</Configuration>
2.3.2、對所有輸出進行編碼處理
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} [%t] %-5p %c - %encode{%m}%n
注意:標準Log4j 1.x不直接支持%encode
,需要自定義PatternLayout或使用擴展庫