Class EntitlementClassResolver


  • public final class EntitlementClassResolver
    extends Object
    Resolves an externally-supplied class name into an instance of an expected entitlement type, safely.

    The entitlement (de)serialization layer stores the concrete implementation class of every nested subject / condition / resource-attribute member as a className string and rebuilds the object graph reflectively. Historically each call site did Class.forName(name) followed by newInstance() and only then cast to the expected type. That is unsafe reflection (CWE-470 / CWE-502): the one-argument Class.forName(String) runs the target class's static initializer at load time and newInstance() runs its no-argument constructor, so an attacker-controlled name executes arbitrary classpath code before the trailing cast can reject it. A cast is not a guard.

    This helper closes that gap: it loads the class without initializing it (the three-argument Class.forName(String, boolean, ClassLoader) form with initialize == false) and verifies it is an instantiable subtype of expectedType before it is ever instantiated. Only genuine, allowed entitlement types are constructed.

    • Method Detail

      • newInstance

        public static <T> T newInstance​(String className,
                                        Class<T> expectedType)
                                 throws ClassNotFoundException,
                                        InstantiationException,
                                        IllegalAccessException
        Loads, validates and instantiates className as an instance of expectedType.
        Type Parameters:
        T - the entitlement type
        Parameters:
        className - the requested implementation class name (may carry surrounding whitespace)
        expectedType - the entitlement type the class must implement or extend
        Returns:
        a new instance of the requested class, guaranteed to be a expectedType
        Throws:
        EntitlementClassResolver.RejectedTypeException - if the class exists but is not an instantiable subtype of expectedType (i.e. the name is not on the allowlist implied by expectedType); the class is never instantiated in this case
        ClassNotFoundException - if the class cannot be loaded at all
        InstantiationException - if the validated class cannot be instantiated, including when its no-argument constructor is missing or throws
        IllegalAccessException - if the validated class's no-argument constructor is inaccessible