All Permissions
4.3 Methods of the Security Manager
4.3.6 Methods Protecting Security Aspects
There are a number of methods in the security manager that protect Java's idea of security itself. These methods are summarized in Table 4−6.
Table 4−6. Security Manager Methods Protecting Java Security
Method
Called By Rationale
checkMemberAccess( )
Class.getFields( ) Class.getMethods( ) Class.getConstructors( ) Class.getField( )
Class.getMethod( ) Class.getConstructor( ) Class.getDeclaredClasses( ) Class.getDeclaredFields( ) Class.getDeclaredMethods( ) Class.getDeclaredConstructors( ) Class.getDeclaredField( )
Class.getDeclaredMethod( ) Class.getDeclardConstructor( )
Untrusted classes can only inspect public information about other classes.
checkPackageAccess( ) Not called
Check if the untrusted class can access classes in a particular package.
checkPackageDefinition( ) Not called
Check if the untrusted class can load classes in a particular package.
checkSecurityAccess( )
Identity.setPublicKey( ) Identity.setInfo( )
Identity.addCertificate( ) Identity.removeCertificate( ) IdentityScope.setSystemScope( ) Provider.clear( )
Provider.put( ) Provider.remove( )
Security.insertProviderAt( ) Security.removeProvider( ) Security.setProperty( ) Signer.getPrivateKey( ) Signer.setKeyPair( )
Untrusted classes cannot manipulate security features.
public void checkMemberAccess(Class clazz, int which)
In Chapter 3, we examined the importance of the access modifiers to the integrity of Java's security model. Java's reflection API allows programs to inspect classes to determine the class's methods, variables, and constructors. The ability to access these entities can impact the memory integrity that Java provides.
The reflection API is powerful enough that, by inspection, a program can determine the private instance variables and methods of a class (although it cannot actually access those variables or call those methods). All classes are allowed to inspect any other class and find out about its public variables and methods. All classes loaded by the same class loader are allowed to inspect all of each other's variables and methods. Otherwise, the current protection domain must carry a runtime permission with a name of accessDeclaredMembers.
The default implementation of this method is very fragile. Unlike all other methods that we'll look at, it is a logical error to override this method and then call super.checkMemberAccess( ).
public void checkSecurityAccess(String action)
In the last half of this book, we'll be examining the details of the Java security package. This package implements a higher−order notion of security, including digital signatures, message digests, public and private keys, etc. The security package depends on this method in the security manager to arbitrate which classes can perform certain security−related operations. As an example, before a class is allowed to read a private key, this method is called with a string indicating that a private key is being read.
Predictably, only trusted classes are allowed to perform any of these security−related operations.
Although the string argument gives the ability to distinguish what operation is being attempted, that argument is typically ignored in present implementations. As we discuss the features of the security package itself, we'll examine how the security package uses this method in more depth.
public void checkPackageAccess(String pkg) public void checkPackageDefinition(String pkg)
These methods are used in conjunction with a class loader. When a class loader is asked to load a class with a particular package name, it will first ask the security manager if it is allowed to do so by calling the checkPackageAccess( ) method. This allows the security manager to make sure that the untrusted class is not trying to use application−specific classes that it shouldn't know about.
Similarly, when a class loader actually creates a class in a particular package, it asks the security manager if it is allowed to do so by calling the checkPackageDefinition( ) method. This allows the security manager to prevent an untrusted class from loading a class from the network and placing it into, for example, the java.lang package.
Notice the distinction between these two methods: in the case of the checkPackageAccess() method, the question is whether the class loader can reference the class at all −− e.g., whether we can call a class in the sun package. In the checkPackageDefinition( ) method, the class bytes have been loaded and the security manager is being asked if they can belong to a particular package.
By default, the checkPackageDefinition( ) method is never called and the
checkPackageAccess( ) method is called only for packages listed in the package.access property within the java.security file. If you write a class loader, you may call it as we indicate in Chapter 6. To succeed, the current protection domain must have a runtime permission with the name defineClassInPackage.+<pkg> or accessClassInPackage.+<pkg>.
That's all the methods of the security manager class that are used by the Java API to perform checks on certain operations. There are other public and protected methods of the SecurityManager class that we have not examined in this chapter; those methods are generally only used when you implement your own security manager without using the access controller, so we will defer their discussion to Appendix D. In the next chapter, we'll discuss how the security manager is usually implemented.
4.4 Comparison with Previous Releases
The security manager has existed in every release of Java. In Java 1.0 and 1.1, the security manager is the only thing that affects the security policy of the program. Because there is no way to install a default security manager via the command line prior to Java 2, most Java 1.0 and 1.1 applications do not have a security manager. In addition, the implementation of the security manager between 1.1−based browsers varies in important aspects between different browser vendors. Even though some browser vendors claim to support the Java 2 platform, they still implement their own security manager rather than using the permission and
policy−based default security manager.
We'll discuss many of the major differences here. In addition, in Appendix D, we'll show how a security manager could be implemented in order to specify a policy for applications run in 1.1.