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:
- No configured permission means No.
- You can only configure what permissions you have, not what you are prohibited to do.
- The same permission can be configured multiple times and can be merged.
- 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 name | Actions allowed by permissions | Risk of allowing this permission |
---|---|---|
createClassLoader | Create class loader | Granting 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. |
getClassLoader | Get 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. |
setContextClassLoader | Settings for the context class loader used by the thread | When 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. |
enableContextClassLoaderOverride | Subclass implementation of thread context class loader method | When 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. |
setSecurityManager | Set 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. |
createSecurityManager | Create a new security manager | Granting 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 variable | This 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 state | This 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.". |
shutdownHooks | Registration and cancellation of virtual machine close hook | This privilege allows an attacker to register a malicious close hook that prevents the virtual machine from shutting down normally. |
setFactory | Set the Socket factory used by ServerSocket or Socket, or the stream handler factory used by URL | This 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. |
setIO | System.out,System.in and system Err settings | This 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. |
modifyThread | Modify the thread, for example, by calling the thread's interrupt, stop, suspend, resume, setDaemon, setPriority, setName, and setUncaughtExceptionHandler methods | This privilege allows an attacker to modify the behavior of any thread in the system. |
stopThread | Stop the thread by calling the thread's stop method | If 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. |
modifyThreadGroup | Modify the thread group, for example, by calling the destroy, getParent, resume, setDaemon, setMaxPriority, stop, and suspend methods of the ThreadGroup | This privilege allows an attacker to create thread groups and set their running priority. |
getProtectionDomain | Gets the ProtectionDomain of the class | This 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. |
getFileSystemAttributes | Get file system properties | This 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. |
readFileDescriptor | Read file descriptor | This permission allows code to read specific files related to file descriptor reading. This can be dangerous if the file contains confidential data. |
writeFileDescriptor | Write file descriptor | This 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 library | Allowing 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 classloader | This 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. |
accessDeclaredMembers | Accessing declared members of a class | This 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. |
queuePrintJob | Start of print job request | This may output sensitive information to the printer or just waste paper. |
getStackTrace | Get 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. |
setDefaultUncaughtExceptionHandler | Sets the default handler to use when a thread terminates abruptly due to an uncapped exception | This privilege allows an attacker to register a malicious uncapped exception handler, which may prevent thread termination |
Preferences | Indicates 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;