java source code analysis - reflection SecurityManager class

java source code analysis - reflection SecurityManager class

In fact, the SecurityManager class is not a member of the reflection related class diagram, but when we view the reflection source code, we often see the following code:

checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);

...
    
private void checkMemberAccess(int which, Class<?> caller, boolean checkProxyInterfaces) {  
        final SecurityManager s = System.getSecurityManager();  //Get security manager
        if (s != null) {
            /* Default policy allows access to all {@link Member#PUBLIC} members,
             * as well as access to classes that have the same class loader as the caller.
             * In all other cases, it requires RuntimePermission("accessDeclaredMembers")
             * permission.
             */
            final ClassLoader ccl = ClassLoader.getClassLoader(caller);
            final ClassLoader cl = getClassLoader0();
            if (which != Member.PUBLIC) {   
                if (ccl != cl) {
                    s.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);    
                }
            }
            this.checkPackageAccess(ccl, checkProxyInterfaces); 
        }
    }

So here is a simple introduction to the SecurityManager to guide what it does. Later, I have the opportunity to have an in-depth understanding.

1. What is it?

SecurityManager is a security manager that allows applications to implement security policies. It allows the application to determine what an operation is and whether to execute it in the security context in which it is allowed before performing a potentially unsafe operation.

2. What can you do?

When running an unknown Java program, the program may have malicious code (deleting system files, restarting the system, etc.). In order to prevent the running of malicious code from affecting the system, it is necessary to control the permissions of the running code. At this time, it is necessary to enable the Java Security Manager to control the permissions of the unknown Java program.

3. How to use it?

3.1 security manager configuration file

The default security manager configuration file is $JAVA_HOME/jre/lib/security/java.policy, that is, when no configuration file is specified, the configuration will be used. The contents are as follows:

// Standard extensions get all permissions by default

grant codeBase "file:${{java.ext.dirs}}/*" {
        permission java.security.AllPermission;
};

// default permissions granted to all domains

grant {
        // Allows any thread to stop itself using the java.lang.Thread.stop()
        // method that takes no argument.
        // Note that this permission is granted by default only to remain
        // backwards compatible.
        // It is strongly recommended that you either remove this permission
        // from this policy file or further restrict it to code sources
        // that you specify, because Thread.stop() is potentially unsafe.
        // See the API specification of java.lang.Thread.stop() for more
        // information.
        permission java.lang.RuntimePermission "stopThread";

        // allows anyone to listen on dynamic ports
        permission java.net.SocketPermission "localhost:0", "listen";

        // "standard" properies that can be read by anyone

        permission java.util.PropertyPermission "java.version", "read";
        permission java.util.PropertyPermission "java.vendor", "read";
        permission java.util.PropertyPermission "java.vendor.url", "read";
        permission java.util.PropertyPermission "java.class.version", "read";
        permission java.util.PropertyPermission "os.name", "read";
        permission java.util.PropertyPermission "os.version", "read";
        permission java.util.PropertyPermission "os.arch", "read";
        permission java.util.PropertyPermission "file.separator", "read";
        permission java.util.PropertyPermission "path.separator", "read";
        permission java.util.PropertyPermission "line.separator", "read";

        permission java.util.PropertyPermission "java.specification.version", "read";
        permission java.util.PropertyPermission "java.specification.vendor", "read";
        permission java.util.PropertyPermission "java.specification.name", "read";

        permission java.util.PropertyPermission "java.vm.specification.version", "read";
        permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
        permission java.util.PropertyPermission "java.vm.specification.name", "read";
        permission java.util.PropertyPermission "java.vm.version", "read";
        permission java.util.PropertyPermission "java.vm.vendor", "read";
        permission java.util.PropertyPermission "java.vm.name", "read";
};

3.2 brief explanation of configuration file

3.2.1 basic principles of configuration

When enabling the security manager, the configuration follows the following basic principles:

  1. No configured permission means No.
  2. You can only configure what permissions you have, not what you are prohibited to do.
  3. The same permission can be configured multiple times and can be merged.
  4. Multiple permissions for unified resources can be separated by commas.

3.2.2 default profile interpretation

Part I authorization:

grant codeBase "file:${{java.ext.dirs}}/*" {
    permission java.security.AllPermission;
};

Authorize the class and jar packages based on the path "file:${{java.ext.dirs} / *". All permissions.

Part II authorization:

grant { 
    permission java.lang.RuntimePermission "stopThread";
    ......   
}

This is fine-grained authorization, which authorizes the operation of some resources. I won't explain specifically. You can check javadoc. For example, the authorized operation of RuntimePermission is as follows:

Permission target nameActions allowed by permissionsRisk of allowing this permission
createClassLoaderCreate class loaderGranting this permission is extremely dangerous. Malicious applications that can instantiate their own class loader may load their own malicious classes in the system. These newly loaded classes may be placed in any protected domain by the class loader, so that the permissions of the domain are automatically granted to these classes.
getClassLoaderGet the class loader (that is, the class loader that calls the class)This will give the attacker permission to get the loader of the specific class. This is dangerous because an attacker can access the class loader of a class, so an attacker can load other classes that can be used for that class loader. Generally, attackers do not have access to these classes.
setContextClassLoaderSettings for the context class loader used by the threadWhen you need to find resources that may not exist in the system class loader, the system code and extension parts use the context class loader. Granting setContextClassLoader permission allows code to change the context class loader used by specific threads, including system threads.
enableContextClassLoaderOverrideSubclass implementation of thread context class loader methodWhen you need to find resources that may not exist in the system class loader, the system code and extension parts use the context class loader. Granting the enableContextClassLoaderOverride permission allows subclasses of threads to override certain methods that are used to get or set the context class loader for a particular thread.
setSecurityManagerSet up security manager (may replace existing)Security manager is a class that allows applications to implement security policies. Granting setSecurityManager permission will allow code to change the security manager used by installing a different and possibly less restrictive security manager, so some checks enforced by the original security manager can be skipped.
createSecurityManagerCreate a new security managerGranting code access to protected, sensitive methods may reveal information about other classes or execution stacks.
getenv.{variable name}Reads the value of the specified environment variableThis permission allows code to read the value of a specific environment variable or determine whether it exists. This authorization is dangerous if the variable contains confidential data.
exitVM.{exit status}Pauses the Java virtual machine with the specified exit stateThis privilege allows an attacker to launch a denial of service attack by automatically forcibly suspending the virtual machine. Note: the "exitVM." permission is automatically granted to all code loaded from the application classpath, so that these applications can abort themselves. In addition, the "exitVM" permission is equal to "exitVM.".
shutdownHooksRegistration and cancellation of virtual machine close hookThis privilege allows an attacker to register a malicious close hook that prevents the virtual machine from shutting down normally.
setFactorySet the Socket factory used by ServerSocket or Socket, or the stream handler factory used by URLThis permission allows code to set the actual implementation of a socket, server socket, stream handler, or RMI socket factory. An attacker may set the wrong implementation, thereby destroying the data flow.
setIOSystem.out,System.in and system Err settingsThis permission allows you to change the value of the standard system flow. An attacker can change the system In to monitor and steal user input, or system Err is set to "null" OutputStream to hide sending to system All error messages for err.
modifyThreadModify the thread, for example, by calling the thread's interrupt, stop, suspend, resume, setDaemon, setPriority, setName, and setUncaughtExceptionHandler methodsThis privilege allows an attacker to modify the behavior of any thread in the system.
stopThreadStop the thread by calling the thread's stop methodIf the system has granted code access to the thread, this permission allows code to stop any thread in the system. This permission is dangerous because the code can break the system by aborting existing threads.
modifyThreadGroupModify the thread group, for example, by calling the destroy, getParent, resume, setDaemon, setMaxPriority, stop, and suspend methods of the ThreadGroupThis privilege allows an attacker to create thread groups and set their running priority.
getProtectionDomainGets the ProtectionDomain of the classThis permission allows code to obtain security policy information for a specific code source. Although obtaining security policy information is not enough to endanger system security, it does provide attackers with other information that can better locate attack targets, such as local file names.
getFileSystemAttributesGet file system propertiesThis permission allows the code to obtain file system information, such as the amount of disk usage or disk space available to the caller. This is potentially dangerous because it divulges information about the system hardware configuration and some information about the caller's write file privileges.
readFileDescriptorRead file descriptorThis permission allows code to read specific files related to file descriptor reading. This can be dangerous if the file contains confidential data.
writeFileDescriptorWrite file descriptorThis permission allows code to write to a specific file associated with the descriptor. This permission is dangerous because it may allow malicious code to spread the virus, or at least fill the entire disk.
loadLibrary. {library name}Dynamically link the specified libraryAllowing applet s to have permission to load native code libraries is dangerous because the Java security architecture is not designed to prevent malicious behavior, nor can it prevent malicious behavior at the level of native code.
accessClassInPackage. {package name}When the classloader calls the checkPackageAccess method of SecurityManager, the specified package is accessed through the loadClass method of the classloaderThis permission allows code to access classes in packages that they normally cannot access. Malicious code may use these classes to help them achieve attempts to undermine system security.
defineClassInPackage. {package name}When the class loader calls the checkPackageDefinition method of SecurityManager, define the classes in the specified package through the defineClass method of the class loader.This permission allows code to define classes in a specific package. This is dangerous because malicious code with this permission may define malicious classes in trusted packages, such as Java Security or Java lang.
accessDeclaredMembersAccessing declared members of a classThis permission allows code to query public, protected, default (package) access and private fields and / or methods of a class. Although the code can access private and protected field and method names, it cannot access private / protected field data and cannot call any private methods. In addition, malicious code may use this information to better locate the attack target. Moreover, it can call any public method in the class and / or access public fields. If the code cannot cast an object to a class / interface with these methods and fields, it usually cannot call these methods and / or access the field, which can be dangerous.
queuePrintJobStart of print job requestThis may output sensitive information to the printer or just waste paper.
getStackTraceGet stack trace information of another thread.This permission allows you to get stack trace information for another thread. This operation may allow malicious code to be executed, monitor threads and discover vulnerabilities in the application.
setDefaultUncaughtExceptionHandlerSets the default handler to use when a thread terminates abruptly due to an uncapped exceptionThis privilege allows an attacker to register a malicious uncapped exception handler, which may prevent thread termination
PreferencesIndicates that you get Java util. prefs. Permissions required for access to preferences. java.util.prefs.Preferences implements the root of the user or system, which in turn allows operations in the preferences persistent internal store to be obtained or updated.If the user running this code has sufficient OS privileges to read / write internal storage, this privilege allows the user to read / write internal storage. The actual internal storage may be located in a traditional file system directory or registry, depending on the platform OS.

3.2.3 detailed description of configurable items

There are three modes for batch configuration:

  • Directory / indicates all the in the directory class file, excluding jar file
  • Directory / * indicates all the in the directory class and jar file
  • Directory / - indicates all the in the directory class and jar files, including subdirectories

You can reference system properties through ${}, such as:

"file:${{java.ext.dirs}}/*"

3.3 start Safety Manager

There are two ways to start safety management. It is recommended to use the start parameter method.

3.3.1 startup parameter mode

When starting the program, start the security manager through additional parameters:

-Djava.security.manager

To specify the location of the configuration file at the same time, an example is as follows:

-Djava.security.manager -Djava.security.policy="E:/java.policy"

3.3.2 coding mode startup

It can also be started by encoding, but it is not recommended:

System.setSecurityManager(new SecurityManager());

Parameter startup is essentially code startup, but parameter startup is flexible. The project startup source code is as follows (sun.misc.Launcher):

// Finally, install a security manager if requested
String s = System.getProperty("java.security.manager");
if (s != null) {
    SecurityManager sm = null;
    if ("".equals(s) || "default".equals(s)) {
        sm = new java.lang.SecurityManager();
    } else {
        try {
            sm = (SecurityManager)loader.loadClass(s).newInstance();
        } catch (IllegalAccessException e) {
        } catch (InstantiationException e) {
        } catch (ClassNotFoundException e) {
        } catch (ClassCastException e) {
        }
    }
    if (sm != null) {
        System.setSecurityManager(sm);
    } else {
        throw new InternalError(
            "Could not create SecurityManager: " + s);
    }
}

It can be found that a default SecurityManager will be created;

Keywords: JDK

Added by OLG on Sun, 23 Jan 2022 04:52:42 +0200