diff --git a/sanitizers/src/main/java/com/code_intelligence/jazzer/sanitizers/Deserialization.kt b/sanitizers/src/main/java/com/code_intelligence/jazzer/sanitizers/Deserialization.kt index d864a164d..261b3cb43 100644 --- a/sanitizers/src/main/java/com/code_intelligence/jazzer/sanitizers/Deserialization.kt +++ b/sanitizers/src/main/java/com/code_intelligence/jazzer/sanitizers/Deserialization.kt @@ -64,7 +64,7 @@ object Deserialization { // We can't instantiate jaz.Zer directly, so we instantiate and serialize jaz.Ter and then // patch the class name. val baos = ByteArrayOutputStream() - ObjectOutputStream(baos).writeObject(jaz.Ter(jaz.Ter.EXPRESSION_LANGUAGE_SANITIZER_ID)) + ObjectOutputStream(baos).writeObject(jaz.Ter(jaz.Ter.DESERIALIZATION_SANITIZER_ID)) val serializedJazTerInstance = baos.toByteArray() val posToPatch = serializedJazTerInstance.indexOf("jaz.Ter".toByteArray()) serializedJazTerInstance[posToPatch + "jaz.".length] = 'Z'.code.toByte() diff --git a/sanitizers/src/test/java/com/example/DisabledHooksTest.java b/sanitizers/src/test/java/com/example/DisabledHooksTest.java index 98d84ba09..76a5e7554 100644 --- a/sanitizers/src/test/java/com/example/DisabledHooksTest.java +++ b/sanitizers/src/test/java/com/example/DisabledHooksTest.java @@ -17,8 +17,10 @@ package com.example; import com.code_intelligence.jazzer.api.FuzzerSecurityIssueHigh; -import java.io.*; -import java.lang.reflect.InvocationTargetException; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.ObjectInputStream; import java.util.Base64; import org.junit.After; import org.junit.Test; @@ -31,15 +33,6 @@ public static void triggerReflectiveCallSanitizer() { } } - public static void triggerExpressionLanguageInjectionSanitizer() throws Throwable { - try { - Class.forName("jaz.Zer").getMethod("el").invoke(null); - } catch (InvocationTargetException e) { - throw e.getCause(); - } catch (IllegalAccessException | ClassNotFoundException | NoSuchMethodException ignore) { - } - } - public static void triggerDeserializationSanitizer() { byte[] data = Base64.getDecoder().decode("rO0ABXNyAAdqYXouWmVyAAAAAAAAACoCAAFCAAlzYW5pdGl6ZXJ4cAEK"); @@ -65,11 +58,6 @@ public void enableDeserializationSanitizer() { triggerDeserializationSanitizer(); } - @Test(expected = FuzzerSecurityIssueHigh.class) - public void enableExpressionLanguageInjectionSanitizer() throws Throwable { - triggerExpressionLanguageInjectionSanitizer(); - } - @Test public void disableReflectiveCallSanitizer() { System.setProperty( @@ -84,14 +72,6 @@ public void disableDeserializationSanitizer() { triggerDeserializationSanitizer(); } - @Test - public void disableExpressionLanguageSanitizer() throws Throwable { - System.setProperty( - "jazzer.disabled_hooks", - "com.code_intelligence.jazzer.sanitizers.ExpressionLanguageInjection"); - triggerExpressionLanguageInjectionSanitizer(); - } - @Test(expected = FuzzerSecurityIssueHigh.class) public void disableReflectiveCallAndEnableDeserialization() { System.setProperty( @@ -104,11 +84,10 @@ public void disableReflectiveCallAndEnableDeserialization() { public void disableAllSanitizers() throws Throwable { System.setProperty( "jazzer.disabled_hooks", - "com.code_intelligence.jazzer.sanitizers.ReflectiveCall," - + "com.code_intelligence.jazzer.sanitizers.Deserialization," - + "com.code_intelligence.jazzer.sanitizers.ExpressionLanguageInjection"); + "com.code_intelligence.jazzer.sanitizers.ReflectiveCall" + + File.pathSeparatorChar + + "com.code_intelligence.jazzer.sanitizers.Deserialization"); triggerReflectiveCallSanitizer(); - triggerExpressionLanguageInjectionSanitizer(); triggerDeserializationSanitizer(); } } diff --git a/src/main/java/jaz/Ter.java b/src/main/java/jaz/Ter.java index 77d93c0a7..717952960 100644 --- a/src/main/java/jaz/Ter.java +++ b/src/main/java/jaz/Ter.java @@ -26,7 +26,6 @@ public class Ter implements java.io.Serializable { public static final byte REFLECTIVE_CALL_SANITIZER_ID = 0; public static final byte DESERIALIZATION_SANITIZER_ID = 1; - public static final byte EXPRESSION_LANGUAGE_SANITIZER_ID = 2; private byte sanitizer = REFLECTIVE_CALL_SANITIZER_ID; diff --git a/src/main/java/jaz/Zer.java b/src/main/java/jaz/Zer.java index 367723a28..69382914c 100644 --- a/src/main/java/jaz/Zer.java +++ b/src/main/java/jaz/Zer.java @@ -18,8 +18,18 @@ import com.code_intelligence.jazzer.api.FuzzerSecurityIssueHigh; import com.code_intelligence.jazzer.api.Jazzer; -import java.io.*; -import java.util.*; +import java.io.Closeable; +import java.io.File; +import java.io.Flushable; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.Serializable; +import java.util.Arrays; +import java.util.Collection; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; import java.util.concurrent.Callable; import java.util.function.Function; @@ -61,7 +71,6 @@ public class Zer // serialized size is 41 bytes private static final byte REFLECTIVE_CALL_SANITIZER_ID = 0; private static final byte DESERIALIZATION_SANITIZER_ID = 1; - private static final byte EXPRESSION_LANGUAGE_SANITIZER_ID = 2; // A byte representing the relevant sanitizer for a given jaz.Zer instance. It is used to check // whether the corresponding sanitizer is disabled and jaz.Zer will not report a finding in this @@ -91,11 +100,13 @@ public Zer(byte sanitizer) { reportFindingIfEnabled(); } - // A special static method that is called by the expression language injection sanitizer. We + // A special static method that is guided to by the expression language injection sanitizer. We // choose a parameterless method to keep the string that the sanitizer guides the fuzzer to // generate within the 64-byte boundary required by the corresponding guiding methods. + // A RCE finding is only reported if the ReflectiveCall sanitizer is active to give users a way to + // silence it. public static void el() { - if (isSanitizerEnabled(EXPRESSION_LANGUAGE_SANITIZER_ID)) { + if (isSanitizerEnabled(REFLECTIVE_CALL_SANITIZER_ID)) { reportFinding(); } } @@ -116,6 +127,7 @@ private static void reportFinding() { } private static boolean isSanitizerEnabled(byte sanitizerId) { + // FIXME: This does not take into account disabled hooks set via CLI args or env. String allDisabledHooks = System.getProperty("jazzer.disabled_hooks"); if (allDisabledHooks == null || allDisabledHooks.equals("")) { return true; @@ -126,13 +138,11 @@ private static boolean isSanitizerEnabled(byte sanitizerId) { case DESERIALIZATION_SANITIZER_ID: sanitizer = "com.code_intelligence.jazzer.sanitizers.Deserialization"; break; - case EXPRESSION_LANGUAGE_SANITIZER_ID: - sanitizer = "com.code_intelligence.jazzer.sanitizers.ExpressionLanguageInjection"; - break; default: sanitizer = "com.code_intelligence.jazzer.sanitizers.ReflectiveCall"; } - return Arrays.stream(allDisabledHooks.split(",")).noneMatch(sanitizer::equals); + return Arrays.stream(allDisabledHooks.split(String.valueOf(File.pathSeparatorChar))) + .noneMatch(sanitizer::equals); } // Getter/Setter