New Rule: Use java.lang.ClassLoader#defineClass with valid ProtectionDomain

  • description of the Rule. It should answer questions “why is there an issue?”, “what could be its impact?” and “what could happen in case of a successful attack?” (for Vulnerabilities and Security Hotspots)
    There are two possible ways to implement and use a custom classloader:
  1. The easy and bad way with https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ClassLoader.html#defineClass(java.lang.String,byte%5B%5D,int,int) which sets the ProtectionDomain of the newly defined class to null
  2. or the more complex and good way with https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ClassLoader.html#defineClass(java.lang.String,java.nio.ByteBuffer,java.security.ProtectionDomain)

If the ProtectionDomain is missing, it is impossible to assign a Permission with the Java Security Manager, neither by policy (JavaSE style) nor by permissions.xml in the deployment (JavaEE style). Therefor the SecurityManager cannot be enabled anymore - jvm wide.

  • snippet of Noncompliant Code
public class BadCustomClassLoader extends ClassLoader {

    @Override
    protected Class<?> findClass(String moduleName, String name) {
        Class<?> result = null;
        // Logic to find already defined classes
        // if not found:
        byte[] theCode = {};
        // Logic to obtain bytecode
        // theCode = ...
        result = defineClass(name, theCode, 0, theCode.length); // Not compliant, no ProtectionDomain
        return result;
    }
  • snippet of Compilant Code (fixing the above noncompliant code)
public class ValidCustomClassLoader extends ClassLoader {

    @Override
    protected Class<?> findClass(String moduleName, String name) {
        Class<?> result = null;
        // Logic to find already defined classes
        // if not found:
        byte[] theCode = {};
        // Logic to obtain bytecode
        // theCode = ...
        CodeSource cs = null; // Logic to create a valid CodeSource missing in the sample
        PermissionCollection pc = null; // Logic to create/obtain a valid PermissionCollection missing in the sample
        ProtectionDomain pd = new ProtectionDomain(cs, pc);
        result = defineClass(name, theCode, 0, theCode.length, pd); // Compliant, ProtectionDomain available
        return result;
    }
  • exceptions to the Noncompliant Code, i.e. conditions in which the noncompliant code should not raise an issue so that we reduce the number of False Positives.
    Not known

  • external references and/or language specifications

  • type : Bug, Vulnerability, Code Smell, Security Hotspot?
    Bug with security impact, because a regular function of Java (the Java Security Manager) is directly affected and will not work