diff --git a/rules/java/lang/dangerous_permissions.yml b/rules/java/lang/dangerous_permissions.yml new file mode 100644 index 000000000..1f489b71b --- /dev/null +++ b/rules/java/lang/dangerous_permissions.yml @@ -0,0 +1,50 @@ +imports: + - java_shared_lang_instance +patterns: + - pattern: | + $.add($); + filters: + - variable: PERMISSION_COLLECTION + detection: java_shared_lang_instance + scope: cursor + filters: + - variable: JAVA_SHARED_LANG_INSTANCE_TYPE + values: + - PermissionCollection + - variable: PERMISSION + detection: java_lang_dangerous_permissions_permissions +auxiliary: + - id: java_lang_dangerous_permissions_permissions + patterns: + - pattern: new RuntimePermission($); + filters: + - variable: CREATE_CLASS_LOADER + string_regex: \AcreateClassLoader\z + - pattern: new ReflectPermission($); + filters: + - variable: SUPPRESS_ACCESS_CHECKS + string_regex: \AsuppressAccessChecks\z +languages: + - java +severity: warning +metadata: + description: "Granting of dangerous permissions detected." + remediation_message: | + ## Description + + It is improper privilege management to grant certain permissions, as these can compromise the security of an application. + + In this case, granting RuntimePermission of `createClassLoader` puts the application at risk of the unauthorized class loaders being instantiated to load arbitrary classes. + Granting ReflectPermission of `suppressAccessChecks` removes Java language access checks, and risks providing unrestricted access to protected and private class members. + + ## Remediations + + ❌ Do not grant RuntimePermission("createClassLoader") permission + + ❌ Do not grant ReflectPermission("suppressAccessChecks") permission + + ✅ Avoid granting the RuntimePermission of createClassLoader to prevent the instantiation of unauthorized class loaders and the loading of arbitrary classes. + cwe_id: + - 269 + id: java_lang_dangerous_permissions + documentation_url: https://docs.bearer.com/reference/rules/java_lang_dangerous_permissions diff --git a/tests/java/lang/dangerous_permissions/test.js b/tests/java/lang/dangerous_permissions/test.js new file mode 100644 index 000000000..9848c071f --- /dev/null +++ b/tests/java/lang/dangerous_permissions/test.js @@ -0,0 +1,18 @@ +const { + createNewInvoker, + getEnvironment, +} = require("../../../helper.js") +const { ruleId, ruleFile, testBase } = getEnvironment(__dirname) + +describe(ruleId, () => { + const invoke = createNewInvoker(ruleId, ruleFile, testBase) + + test("dangerous_permissions", () => { + const testCase = "main.java" + + const results = invoke(testCase) + + expect(results.Missing).toEqual([]) + expect(results.Extra).toEqual([]) + }) +}) \ No newline at end of file diff --git a/tests/java/lang/dangerous_permissions/testdata/main.java b/tests/java/lang/dangerous_permissions/testdata/main.java new file mode 100644 index 000000000..96478c8a7 --- /dev/null +++ b/tests/java/lang/dangerous_permissions/testdata/main.java @@ -0,0 +1,33 @@ +// License: LGPL-3.0 License (c) find-sec-bugs +package perm; +import java.lang.reflect.ReflectPermission; +import java.security.CodeSource; +import java.security.PermissionCollection; +import java.util.ArrayList; +import java.util.List; + +public class DangerousPermissions { + public void bad(CodeSource codesource) { + PermissionCollection coll = super.getPermissions(codesource); + // bearer:expected java_lang_dangerous_permissions + coll.add(new ReflectPermission("suppressAccessChecks")); + // bearer:expected java_lang_dangerous_permissions + coll.add(new RuntimePermission("createClassLoader")); + RuntimePermission perm = new RuntimePermission("createClassLoader"); + // bearer:expected java_lang_dangerous_permissions + coll.add(perm); + ReflectPermission p = new ReflectPermission("suppressAccessChecks"); + // bearer:expected java_lang_dangerous_permissions + coll.add(p); + } + + public void ok(CodeSource codesource) { + RuntimePermission permission = new RuntimePermission("createClassLoader"); + List list = new ArrayList<>(); + list.add(permission); + + ReflectPermission perm = new ReflectPermission("newProxyInPackage"); + PermissionCollection pc = super.getPermissions(codesource); + pc.add(perm); + } +}