diff --git a/provider/fastbin/src/main/java/org/apache/aries/rsa/provider/fastbin/api/ObjectSerializationStrategy.java b/provider/fastbin/src/main/java/org/apache/aries/rsa/provider/fastbin/api/ObjectSerializationStrategy.java
index ea23fb25..40324fef 100644
--- a/provider/fastbin/src/main/java/org/apache/aries/rsa/provider/fastbin/api/ObjectSerializationStrategy.java
+++ b/provider/fastbin/src/main/java/org/apache/aries/rsa/provider/fastbin/api/ObjectSerializationStrategy.java
@@ -23,6 +23,7 @@
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -34,25 +35,31 @@
import org.fusesource.hawtbuf.DataByteArrayOutputStream;
import org.osgi.framework.ServiceException;
-/**
- *
- *
- *
- */
public class ObjectSerializationStrategy implements SerializationStrategy {
public static final ObjectSerializationStrategy INSTANCE = new ObjectSerializationStrategy();
private static final ObjectSerializationStrategy V1 = INSTANCE;
- private int protocolVersion = FastBinProvider.PROTOCOL_VERSION;
+ // private int protocolVersion = FastBinProvider.PROTOCOL_VERSION
- private static final Set ALLOWEDCLASSES;
+ private static final Set DENIED_CLASSES;
+ private static final Set ALLOWED_CLASSES;
private static final FilteredClassLoaderObjectInputStream.AllowlistPackagesPredicate ALLOWED_PACKAGES;
+ private static final String ADDITIONAL_DENIED_CLASSES = System.getProperty( "org.apache.aries.rsa.provider.fastbin.api.DESERIALIZATION_CLASS_DENY_LIST", "");
private static final String ADDITIONAL_ALLOWED_PACKAGE = System.getProperty( "org.apache.aries.rsa.provider.fastbin.api.DESERIALIZATION_PACKAGE_ALLOW_LIST", "");
private static final String ADDITIONAL_ALLOWED_CLASSES = System.getProperty( "org.apache.aries.rsa.provider.fastbin.api.DESERIALIZATION_CLASS_ALLOW_LIST", "");
static
{
- Set classes = new HashSet<>();
- classes.addAll(Arrays.asList(
+ // denied classes
+ Set deniedClasses = new HashSet<>(Arrays.asList("java.net.URL", "[Ljava.net.URL"));
+ final String[] customDeniedClasses = ADDITIONAL_DENIED_CLASSES.split(",");
+ if (customDeniedClasses.length > 0)
+ {
+ deniedClasses.addAll(Arrays.asList(customDeniedClasses));
+ }
+ DENIED_CLASSES = deniedClasses;
+
+ // allowed classes
+ Set allowedClasses = new HashSet<>(Arrays.asList(
"B", // byte
"C", // char
"D", // double
@@ -62,16 +69,16 @@ public class ObjectSerializationStrategy implements SerializationStrategy {
"S", // short
"Z", // boolean
"L" // Object type (LClassName;)
- ));
- final String[] customClasses = ADDITIONAL_ALLOWED_CLASSES.split(",");
- if (customClasses.length > 0)
+ ));
+ final String[] customAllowedClasses = ADDITIONAL_ALLOWED_CLASSES.split(",");
+ if (customAllowedClasses.length > 0)
{
- classes.addAll(Arrays.asList(customClasses));
+ allowedClasses.addAll(Arrays.asList(customAllowedClasses));
}
- ALLOWEDCLASSES = classes;
+ ALLOWED_CLASSES = allowedClasses;
- List packages = new ArrayList<>();
- packages.addAll(Arrays.asList(
+ // allowed packages
+ List packages = new ArrayList<>(Arrays.asList(
"java",
"javax",
"Ljava",
@@ -100,7 +107,7 @@ public void encodeRequest(ClassLoader loader, Class>[] types, Object[] args, D
}
public void decodeResponse(ClassLoader loader, Class> type, DataByteArrayInputStream source, AsyncCallback result) throws IOException, ClassNotFoundException {
- ClassLoaderObjectInputStream ois = new FilteredClassLoaderObjectInputStream(source, ALLOWEDCLASSES, ALLOWED_PACKAGES);
+ ClassLoaderObjectInputStream ois = new FilteredClassLoaderObjectInputStream(source, DENIED_CLASSES, ALLOWED_CLASSES, ALLOWED_PACKAGES);
ois.setClassLoader(loader);
Throwable error = (Throwable) ois.readObject();
Object value = ois.readObject();
@@ -112,7 +119,7 @@ public void decodeResponse(ClassLoader loader, Class> type, DataByteArrayInput
}
public void decodeRequest(ClassLoader loader, Class>[] types, DataByteArrayInputStream source, Object[] target) throws IOException, ClassNotFoundException {
- ClassLoaderObjectInputStream ois = new FilteredClassLoaderObjectInputStream(source, ALLOWEDCLASSES, ALLOWED_PACKAGES);
+ ClassLoaderObjectInputStream ois = new FilteredClassLoaderObjectInputStream(source, DENIED_CLASSES, ALLOWED_CLASSES, ALLOWED_PACKAGES);
ois.setClassLoader(loader);
final Object[] args = (Object[]) ois.readObject();
if( args!=null ) {
diff --git a/provider/fastbin/src/main/java/org/apache/aries/rsa/provider/fastbin/util/FilteredClassLoaderObjectInputStream.java b/provider/fastbin/src/main/java/org/apache/aries/rsa/provider/fastbin/util/FilteredClassLoaderObjectInputStream.java
index 3fe1ffa9..60be7dcf 100644
--- a/provider/fastbin/src/main/java/org/apache/aries/rsa/provider/fastbin/util/FilteredClassLoaderObjectInputStream.java
+++ b/provider/fastbin/src/main/java/org/apache/aries/rsa/provider/fastbin/util/FilteredClassLoaderObjectInputStream.java
@@ -30,22 +30,25 @@ public class FilteredClassLoaderObjectInputStream extends ClassLoaderObjectInput
static final String PROPERTY_USE_INSECURE_DESERIALIZATION = "org.apache.aries.rsa.provider.fastbin.util.useInsecureDeserialization";
static boolean useInsecureDeserialization = Boolean.getBoolean(PROPERTY_USE_INSECURE_DESERIALIZATION);
+ private final Set deniedClasses;
private final Set allowedClasses;
- private Predicate allowedPackages;
+ private final Predicate allowedPackages;
- public FilteredClassLoaderObjectInputStream(InputStream s, Set allowedClasses)
+ public FilteredClassLoaderObjectInputStream(InputStream inArg, Set allowedClasses)
throws IOException
{
- super(s);
+ super(inArg);
if (allowedClasses == null)
{
throw new IllegalArgumentException("allowedClasses must not be null");
}
+ this.deniedClasses = null;
this.allowedClasses = allowedClasses;
+ this.allowedPackages = null;
}
- public FilteredClassLoaderObjectInputStream(InputStream inArg, Set allowedClasses, Predicate allowedPackages)
+ public FilteredClassLoaderObjectInputStream(InputStream inArg, Set deniedClasses, Set allowedClasses, Predicate allowedPackages)
throws IOException
{
super(inArg);
@@ -55,6 +58,7 @@ public FilteredClassLoaderObjectInputStream(InputStream inArg, Set allow
throw new IllegalArgumentException("allowedClasses must not be null");
}
+ this.deniedClasses = deniedClasses;
this.allowedClasses = allowedClasses;
this.allowedPackages = allowedPackages;
}
@@ -67,6 +71,10 @@ public FilteredClassLoaderObjectInputStream(InputStream inArg, Set allow
if (!useInsecureDeserialization)
{
+ if (deniedClasses != null && deniedClasses.contains(className))
+ {
+ throw new InvalidClassException(className, "Invalid de-serialization data. POSSIBLE ATTACK. Invalid class=" + className);
+ }
if (allowedClasses.contains(className))
{
return super.resolveClass(clsDescriptor);
@@ -75,7 +83,7 @@ public FilteredClassLoaderObjectInputStream(InputStream inArg, Set allow
{
return super.resolveClass(clsDescriptor);
}
- throw new InvalidClassException(className, "Invalid de-serialisation data. POSSIBLE ATTACK. Invalid class=" + className);
+ throw new InvalidClassException(className, "Invalid de-serialization data. POSSIBLE ATTACK. Invalid class=" + className);
}
return super.resolveClass(clsDescriptor);