Skip to content

Commit

Permalink
prevent DOS attacks using on malicious serialized input
Browse files Browse the repository at this point in the history
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
  • Loading branch information
ceki committed Nov 27, 2023
1 parent d87dd12 commit b8eac23
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 7 deletions.
Expand Up @@ -14,6 +14,7 @@
package ch.qos.logback.classic.spi;

import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
Expand All @@ -28,6 +29,7 @@
import ch.qos.logback.classic.Level;

// http://www.riehle.org/computer-science/research/1998/ubilab-tr-1998-10-1.html
// See also the paper https://www.riehle.org/computer-science/research/1998/ubilab-tr-1998-10-1.pdf

/**
* A read-only and serializable implementation of {@link ILoggingEvent}.
Expand All @@ -41,6 +43,7 @@ public class LoggingEventVO implements ILoggingEvent, Serializable {

private static final int NULL_ARGUMENT_ARRAY = -1;
private static final String NULL_ARGUMENT_ARRAY_ELEMENT = "NULL_ARGUMENT_ARRAY_ELEMENT";
private static final int ARGUMENT_ARRAY_DESERIALIZATION_LIMIT = 128;

private String threadName;
private String loggerName;
Expand Down Expand Up @@ -203,6 +206,12 @@ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundE
level = Level.toLevel(levelInt);

int argArrayLen = in.readInt();

// Prevent DOS attacks via large or negative arrays
if (argArrayLen < 0 || argArrayLen > ARGUMENT_ARRAY_DESERIALIZATION_LIMIT) {
throw new InvalidObjectException("Argument array length is invalid: " + argArrayLen);
}

if (argArrayLen != NULL_ARGUMENT_ARRAY) {
argumentArray = new String[argArrayLen];
for (int i = 0; i < argArrayLen; i++) {
Expand Down
Expand Up @@ -16,6 +16,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.InvalidClassException;
import java.io.ObjectInputFilter;
import java.io.ObjectInputStream;
import java.io.ObjectStreamClass;
import java.util.ArrayList;
Expand All @@ -36,20 +37,27 @@
*/
public class HardenedObjectInputStream extends ObjectInputStream {

final List<String> whitelistedClassNames;
final static String[] JAVA_PACKAGES = new String[] { "java.lang", "java.util" };
final private List<String> whitelistedClassNames;
final private static String[] JAVA_PACKAGES = new String[] { "java.lang", "java.util" };
final private static int DEPTH_LIMIT = 16;
final private static int ARRAY_LIMIT = 10000;

public HardenedObjectInputStream(InputStream in, String[] whilelist) throws IOException {
public HardenedObjectInputStream(InputStream in, String[] whitelist) throws IOException {
super(in);

this.initObjectFilter();
this.whitelistedClassNames = new ArrayList<String>();
if (whilelist != null) {
for (int i = 0; i < whilelist.length; i++) {
this.whitelistedClassNames.add(whilelist[i]);
if (whitelist != null) {
for (int i = 0; i < whitelist.length; i++) {
this.whitelistedClassNames.add(whitelist[i]);
}
}
}

private void initObjectFilter() {
this.setObjectInputFilter(ObjectInputFilter.Config.createFilter(
"maxarray=" + ARRAY_LIMIT + ";maxdepth=" + DEPTH_LIMIT + ";"
));
}
public HardenedObjectInputStream(InputStream in, List<String> whitelist) throws IOException {
super(in);

Expand Down

0 comments on commit b8eac23

Please sign in to comment.