diff options
author | Fabian Meumertzheim <meumertzheim@code-intelligence.com> | 2021-03-01 18:04:53 +0100 |
---|---|---|
committer | Fabian Meumertzheim <fabian@meumertzhe.im> | 2021-03-04 12:54:58 +0100 |
commit | 3ad06ca2c6d7f65b9ce467c298ec53730fbdc52d (patch) | |
tree | 51ae88a7cf7bc5a6cb6e2b32938b0164f0e7466b /examples/src | |
parent | 901ec0ffcf392e97a6213555e257f57b1977e93c (diff) | |
download | jazzer-api-3ad06ca2c6d7f65b9ce467c298ec53730fbdc52d.tar.gz |
Rewrite the example fuzz targets to use SecurityBug and assert
Also split up JsonSanitizerFuzzer into four individual fuzzers.
Diffstat (limited to 'examples/src')
-rw-r--r-- | examples/src/main/java/com/example/ExampleFuzzer.java | 3 | ||||
-rw-r--r-- | examples/src/main/java/com/example/ExampleValueProfileFuzzer.java | 3 | ||||
-rw-r--r-- | examples/src/main/java/com/example/JsonSanitizerCrashFuzzer.java | 30 | ||||
-rw-r--r-- | examples/src/main/java/com/example/JsonSanitizerDenylistFuzzer.java | 45 | ||||
-rw-r--r-- | examples/src/main/java/com/example/JsonSanitizerIdempotenceFuzzer.java | 34 | ||||
-rw-r--r-- | examples/src/main/java/com/example/JsonSanitizerValidJsonFuzzer.java (renamed from examples/src/main/java/com/example/JsonSanitizerFuzzer.java) | 23 |
6 files changed, 125 insertions, 13 deletions
diff --git a/examples/src/main/java/com/example/ExampleFuzzer.java b/examples/src/main/java/com/example/ExampleFuzzer.java index b41f9c77..073d924a 100644 --- a/examples/src/main/java/com/example/ExampleFuzzer.java +++ b/examples/src/main/java/com/example/ExampleFuzzer.java @@ -15,6 +15,7 @@ package com.example; import com.code_intelligence.jazzer.api.FuzzedDataProvider; +import com.code_intelligence.jazzer.api.FuzzerSecurityIssueMedium; import java.security.SecureRandom; public class ExampleFuzzer { @@ -34,6 +35,6 @@ public class ExampleFuzzer { } private static void mustNeverBeCalled() { - throw new IllegalStateException("mustNeverBeCalled has been called"); + throw new FuzzerSecurityIssueMedium("mustNeverBeCalled has been called"); } } diff --git a/examples/src/main/java/com/example/ExampleValueProfileFuzzer.java b/examples/src/main/java/com/example/ExampleValueProfileFuzzer.java index 1200c560..acc023a2 100644 --- a/examples/src/main/java/com/example/ExampleValueProfileFuzzer.java +++ b/examples/src/main/java/com/example/ExampleValueProfileFuzzer.java @@ -15,6 +15,7 @@ package com.example; import com.code_intelligence.jazzer.api.FuzzedDataProvider; +import com.code_intelligence.jazzer.api.FuzzerSecurityIssueLow; import java.util.Base64; public class ExampleValueProfileFuzzer { @@ -47,6 +48,6 @@ public class ExampleValueProfileFuzzer { } private static void mustNeverBeCalled() { - throw new IllegalStateException("mustNeverBeCalled has been called"); + throw new FuzzerSecurityIssueLow("mustNeverBeCalled has been called"); } } diff --git a/examples/src/main/java/com/example/JsonSanitizerCrashFuzzer.java b/examples/src/main/java/com/example/JsonSanitizerCrashFuzzer.java new file mode 100644 index 00000000..05ac4611 --- /dev/null +++ b/examples/src/main/java/com/example/JsonSanitizerCrashFuzzer.java @@ -0,0 +1,30 @@ +// 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 com.google.json.JsonSanitizer; + +public class JsonSanitizerCrashFuzzer { + public static void fuzzerTestOneInput(FuzzedDataProvider data) { + String input = data.consumeRemainingAsString(); + try { + JsonSanitizer.sanitize(input, 10); + } catch (ArrayIndexOutOfBoundsException ignored) { + // ArrayIndexOutOfBoundsException is expected if nesting depth is + // exceeded. + } + } +} diff --git a/examples/src/main/java/com/example/JsonSanitizerDenylistFuzzer.java b/examples/src/main/java/com/example/JsonSanitizerDenylistFuzzer.java new file mode 100644 index 00000000..e715b1d9 --- /dev/null +++ b/examples/src/main/java/com/example/JsonSanitizerDenylistFuzzer.java @@ -0,0 +1,45 @@ +// 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 com.code_intelligence.jazzer.api.FuzzerSecurityIssueHigh; +import com.code_intelligence.jazzer.api.FuzzerSecurityIssueMedium; +import com.google.json.JsonSanitizer; + +public class JsonSanitizerDenylistFuzzer { + public static void fuzzerTestOneInput(FuzzedDataProvider data) { + String input = data.consumeRemainingAsString(); + String validJson; + try { + validJson = JsonSanitizer.sanitize(input, 10); + } catch (Exception e) { + return; + } + + // Check for forbidden substrings. As these would enable Cross-Site Scripting, treat every + // finding as a high severity vulnerability. + assert !validJson.contains("</script") + : new FuzzerSecurityIssueHigh("Output contains </script"); + assert !validJson.contains("]]>") : new FuzzerSecurityIssueHigh("Output contains ]]>"); + + // Check for more forbidden substrings. As these would not directly enable Cross-Site Scripting + // in general, but may impact script execution on the embedding page, treat each finding as a + // medium severity vulnerability. + assert !validJson.contains("<script") + : new FuzzerSecurityIssueMedium("Output contains <script"); + assert !validJson.contains("<!--") : new FuzzerSecurityIssueMedium("Output contains <!--"); + } +} diff --git a/examples/src/main/java/com/example/JsonSanitizerIdempotenceFuzzer.java b/examples/src/main/java/com/example/JsonSanitizerIdempotenceFuzzer.java new file mode 100644 index 00000000..111d3de2 --- /dev/null +++ b/examples/src/main/java/com/example/JsonSanitizerIdempotenceFuzzer.java @@ -0,0 +1,34 @@ +// 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 com.google.json.JsonSanitizer; + +public class JsonSanitizerIdempotenceFuzzer { + public static void fuzzerTestOneInput(FuzzedDataProvider data) { + String input = data.consumeRemainingAsString(); + String validJson; + try { + validJson = JsonSanitizer.sanitize(input, 10); + } catch (Exception e) { + return; + } + + // Ensure that sanitizing twice does not give different output (idempotence). Since failure to + // be idempotent is not a security issue in itself, fail with a regular AssertionError. + assert JsonSanitizer.sanitize(validJson).equals(validJson) : "Not idempotent"; + } +} diff --git a/examples/src/main/java/com/example/JsonSanitizerFuzzer.java b/examples/src/main/java/com/example/JsonSanitizerValidJsonFuzzer.java index 31831616..f82381cb 100644 --- a/examples/src/main/java/com/example/JsonSanitizerFuzzer.java +++ b/examples/src/main/java/com/example/JsonSanitizerValidJsonFuzzer.java @@ -15,27 +15,28 @@ package com.example; import com.code_intelligence.jazzer.api.FuzzedDataProvider; +import com.code_intelligence.jazzer.api.FuzzerSecurityIssueLow; import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.json.JsonSanitizer; -public class JsonSanitizerFuzzer { +public class JsonSanitizerValidJsonFuzzer { public static void fuzzerTestOneInput(FuzzedDataProvider data) { String input = data.consumeRemainingAsString(); String validJson; try { - validJson = JsonSanitizer.sanitize(input, 60); - } catch (ArrayIndexOutOfBoundsException e) { - // ArrayIndexOutOfBoundsException is expected if nesting depth is - // exceeded. + validJson = JsonSanitizer.sanitize(input, 10); + } catch (Exception e) { return; } - Gson gson = new Gson(); - gson.fromJson(validJson, JsonElement.class); - if (validJson.contains("</script>") || validJson.contains("<script") - || validJson.contains("<!--") || validJson.contains("]]>")) { - System.out.println(validJson); - throw new IllegalStateException("Output contains forbidden substring"); + + // Check that the output is valid JSON. Invalid JSON may crash other parts of the application + // that trust the output of the sanitizer. + try { + Gson gson = new Gson(); + gson.fromJson(validJson, JsonElement.class); + } catch (Exception e) { + throw new FuzzerSecurityIssueLow("Not idempotent", e); } } } |