aboutsummaryrefslogtreecommitdiff
path: root/sanitizers
diff options
context:
space:
mode:
authorFabian Meumertzheim <meumertzheim@code-intelligence.com>2021-05-14 10:11:59 +0200
committerFabian Meumertzheim <fabian@meumertzhe.im>2021-05-14 11:12:43 +0200
commitf16d957d528fe0a0795114e39f0bda575e4caaff (patch)
tree6900517b8a039dcec1f30984582cb7e7c02ca056 /sanitizers
parent3e1e48a5eae1b322844feba46a99a072a18230ee (diff)
downloadjazzer-api-f16d957d528fe0a0795114e39f0bda575e4caaff.tar.gz
Add a sanitizer for arbitrary reflective calls
Diffstat (limited to 'sanitizers')
-rw-r--r--sanitizers/sanitizers.bzl1
-rw-r--r--sanitizers/src/main/java/com/code_intelligence/jazzer/sanitizers/ReflectiveCall.kt38
-rw-r--r--sanitizers/src/test/java/com/example/BUILD.bazel8
-rw-r--r--sanitizers/src/test/java/com/example/ReflectiveCall.java32
4 files changed, 79 insertions, 0 deletions
diff --git a/sanitizers/sanitizers.bzl b/sanitizers/sanitizers.bzl
index 142c4996..fc93ddb5 100644
--- a/sanitizers/sanitizers.bzl
+++ b/sanitizers/sanitizers.bzl
@@ -16,6 +16,7 @@ _sanitizer_package_prefix = "com.code_intelligence.jazzer.sanitizers."
_sanitizer_class_names = [
"Deserialization",
+ "ReflectiveCall",
]
SANITIZER_CLASSES = [_sanitizer_package_prefix + class_name for class_name in _sanitizer_class_names]
diff --git a/sanitizers/src/main/java/com/code_intelligence/jazzer/sanitizers/ReflectiveCall.kt b/sanitizers/src/main/java/com/code_intelligence/jazzer/sanitizers/ReflectiveCall.kt
new file mode 100644
index 00000000..d1129fc9
--- /dev/null
+++ b/sanitizers/src/main/java/com/code_intelligence/jazzer/sanitizers/ReflectiveCall.kt
@@ -0,0 +1,38 @@
+// Copyright 2021 Code Intelligence GmbH
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.code_intelligence.jazzer.sanitizers
+
+import com.code_intelligence.jazzer.api.HookType
+import com.code_intelligence.jazzer.api.Jazzer
+import com.code_intelligence.jazzer.api.MethodHook
+import java.lang.invoke.MethodHandle
+
+/**
+ * Detects unsafe reflective calls that lead to attacker-controlled method calls.
+ */
+object ReflectiveCall {
+
+ /**
+ * jaz.Zer is a honeypot class: All of its methods report a finding when called.
+ */
+ private const val HONEYPOT_CLASS_NAME = "jaz.Zer"
+
+ @MethodHook(type = HookType.BEFORE, targetClassName = "java.lang.Class", targetMethod = "forName")
+ @JvmStatic
+ fun classForNameHook(method: MethodHandle?, alwaysNull: Any?, args: Array<Any?>, hookId: Int) {
+ val className = args[0] as? String ?: return
+ Jazzer.guideTowardsEquality(className, HONEYPOT_CLASS_NAME, hookId)
+ }
+}
diff --git a/sanitizers/src/test/java/com/example/BUILD.bazel b/sanitizers/src/test/java/com/example/BUILD.bazel
index cd47a7f9..f86b6922 100644
--- a/sanitizers/src/test/java/com/example/BUILD.bazel
+++ b/sanitizers/src/test/java/com/example/BUILD.bazel
@@ -7,3 +7,11 @@ java_fuzz_target_test(
],
target_class = "com.example.ObjectInputStreamDeserialization",
)
+
+java_fuzz_target_test(
+ name = "ReflectiveCall",
+ srcs = [
+ "ReflectiveCall.java",
+ ],
+ target_class = "com.example.ReflectiveCall",
+)
diff --git a/sanitizers/src/test/java/com/example/ReflectiveCall.java b/sanitizers/src/test/java/com/example/ReflectiveCall.java
new file mode 100644
index 00000000..7f85e486
--- /dev/null
+++ b/sanitizers/src/test/java/com/example/ReflectiveCall.java
@@ -0,0 +1,32 @@
+// Copyright 2021 Code Intelligence GmbH
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.example;
+
+import com.code_intelligence.jazzer.api.FuzzedDataProvider;
+import java.lang.reflect.InvocationTargetException;
+
+public class ReflectiveCall {
+ public static void fuzzerTestOneInput(FuzzedDataProvider data) {
+ String input = data.consumeRemainingAsAsciiString();
+ if (input.startsWith("@")) {
+ String className = input.substring(1);
+ try {
+ Class.forName(className).getConstructor().newInstance();
+ } catch (InstantiationException | IllegalAccessException | InvocationTargetException
+ | NoSuchMethodException | ClassNotFoundException ignored) {
+ }
+ }
+ }
+}