Last active
March 31, 2016 07:37
-
-
Save cedricvidal/136673c4978dc9f426167421f693e7bf to your computer and use it in GitHub Desktop.
Logback timestamp tampering example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project xmlns="http://maven.apache.org/POM/4.0.0" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |
<modelVersion>4.0.0</modelVersion> | |
<groupId>com.quicksign.poc</groupId> | |
<artifactId>qs-logback-timestamp-altering</artifactId> | |
<version>1.0-SNAPSHOT</version> | |
<dependencies> | |
<dependency> | |
<groupId>ch.qos.logback</groupId> | |
<artifactId>logback-classic</artifactId> | |
<version>1.0.7</version> | |
</dependency> | |
<dependency> | |
<groupId>junit</groupId> | |
<artifactId>junit</artifactId> | |
<version>4.12</version> | |
</dependency> | |
<dependency> | |
<groupId>org.mockito</groupId> | |
<artifactId>mockito-all</artifactId> | |
<version>1.10.19</version> | |
</dependency> | |
</dependencies> | |
</project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import ch.qos.logback.classic.Level; | |
import ch.qos.logback.classic.Logger; | |
import ch.qos.logback.classic.spi.LoggingEvent; | |
/** | |
* @author <a href="mailto:[email protected]">Cedric Vidal, Quicksign</a> | |
*/ | |
public class TamperedTimestampLoggingEvent extends LoggingEvent { | |
private final long tamperedTimestamp; | |
public TamperedTimestampLoggingEvent(String fqcn, Logger logger, Level level, String message, Throwable throwable, Object[] argArray, long tamperedTimestamp) { | |
super(fqcn, logger, level, message, throwable, argArray); | |
this.tamperedTimestamp = tamperedTimestamp; | |
} | |
@Override | |
public long getTimeStamp() { | |
return tamperedTimestamp; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import ch.qos.logback.classic.Level; | |
import ch.qos.logback.classic.Logger; | |
import org.slf4j.LoggerFactory; | |
/** | |
* @author <a href="mailto:[email protected]">Cedric Vidal, Quicksign</a> | |
*/ | |
public class TamperedTimestampLoggingEventExample { | |
public static void main(String[] args) { | |
// One hour in the futur | |
final long tamperedTimestamp = System.currentTimeMillis() + 60 * 60 * 1000; | |
final String fqcn = "com.foo.bar"; | |
Logger logger = (Logger) LoggerFactory.getLogger(fqcn); | |
final TamperedTimestampLoggingEvent event = new TamperedTimestampLoggingEvent(fqcn, logger, Level.INFO, "Hello", null, null, tamperedTimestamp); | |
logger.callAppenders(event); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import ch.qos.logback.classic.Level; | |
import ch.qos.logback.classic.Logger; | |
import ch.qos.logback.classic.LoggerContext; | |
import ch.qos.logback.classic.spi.ILoggingEvent; | |
import ch.qos.logback.core.Appender; | |
import ch.qos.logback.core.status.OnConsoleStatusListener; | |
import org.junit.Before; | |
import org.junit.Test; | |
import org.mockito.*; | |
import org.slf4j.LoggerFactory; | |
import static org.junit.Assert.assertEquals; | |
/** | |
* @author <a href="mailto:[email protected]">Cedric Vidal, Quicksign</a> | |
*/ | |
public class TamperedTimestampLoggingEventTest { | |
@Captor | |
ArgumentCaptor<ILoggingEvent> captor; | |
@Before | |
public void init(){ | |
MockitoAnnotations.initMocks(this); | |
} | |
@Test | |
public void testTamperTimestamp() { | |
// Using context that way instead of default context allows to mock components | |
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); | |
// Remove default configuration | |
context.reset(); | |
// Printout configuration problems | |
final OnConsoleStatusListener statusListener = new OnConsoleStatusListener(); | |
statusListener.setContext(context); | |
statusListener.start(); | |
context.getStatusManager().add(statusListener); | |
// Create mock appender which will allow to assert that the timestamp passed to it is actually tampered | |
final Appender<ILoggingEvent> appender = Mockito.mock(Appender.class); | |
appender.setContext(context); | |
appender.start(); | |
// Register mock appender | |
context.getLogger("ROOT").addAppender(appender); | |
// Call appenders using logback API with a TamperedTimestampLoggingEvent | |
final String fqcn = "com.foo.bar"; | |
final long tamperedTimestamp = System.currentTimeMillis() + 60 * 60 * 1000; | |
Logger logger = context.getLogger(fqcn); | |
final TamperedTimestampLoggingEvent event = new TamperedTimestampLoggingEvent(fqcn, logger, Level.INFO, "Hello", null, null, tamperedTimestamp); | |
logger.callAppenders(event); | |
// Check that the actual logged event timestamp has been tampered | |
Mockito.verify(appender).doAppend(captor.capture()); | |
final ILoggingEvent actualLoggedEvent = captor.getValue(); | |
assertEquals("Hello", actualLoggedEvent.getMessage()); | |
assertEquals(tamperedTimestamp, actualLoggedEvent.getTimeStamp()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment