In Chapter 3, we examined the importance of the access modifiers to the integrity of Javas security model. Javas reflection API allows programs to inspect classes to determine the classs 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
others 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 well look at, it is a logical error to override this method and then call
super.checkMemberAccess .
public void checkSecurityAccessString action In the last half of this book, well 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, well examine how the security package uses this method in more depth.
public void checkPackageAccessString pkg public void checkPackageDefinitionString 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 shouldnt 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
. 72
Thats 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, well 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.
Well discuss many of the major differences here. In addition, in Appendix D, well show how a security manager could be implemented in order to specify a policy for applications run in 1.1.
4.4.1 Trusted and Untrusted Classes
The default notion of what constitutes a trusted class has changed significantly between releases of Java: In Java 1.0, a class that is loaded from the classpath is considered trusted and a class that is loaded
from a class loader is considered untrusted. •
In Java 1.1, the same rule applies but a class that is loaded from a jar file may carry with it a digital signature that allows it to be given extra privileges. These privileges are typically all−or−nothing: if
you trust the entity that signed the jar file, then that code can do anything it wants. Some browser vendors have extended that behavior using proprietary APIs.
•
In Java 2, only classes in the core API are considered trusted. Other classes must be given explicit permission to perform the operations weve discussed.
•
4.4.2 Differences in the Security Manager Class
In 1.1, the setSecurityManager
method can only be called once, and once installed, the security manager cannot be removed. Attempting to call this method after a security manger has already been installed
will result in a SecurityException
.
4.4.2.1 File access
While 1.1−based browsers like Netscape Navigator 4 and earlier, Internet Explorer, and HotJava all have a default policy that prevents untrusted classes from all file access, some of them allow the user to configure a
different policy. HotJava and the appletviewer
, for example, allow the user to create a set of directories in which applets can read and write files, and some versions of Internet Explorer allow the user to grant file
access to all untrusted classes.
4.4.2.2 Network access
There was a change in the default security policy supplied in 1.0 and in 1.1 with respect to untrusted classes and server sockets either instances of class
ServerSocket or datagram sockets that received data from
any source. In 1.0, untrusted classes were typically not allowed to create a server socket at all, which meant that the
checkListen and
checkAccept methods always threw a security exception when an
applet attempted such an operation. In 1.1 and later, untrusted classes are allowed to create a server socket so long as the port number of that socket is greater than the privileged port number on the machine typically
1024. Note too that the receive
method of the DatagramSocket
class in Java 2 now calls the checkAccept
rather than the checkConnect
method. Suns 1.1−based browsers HotJava and
appletviewer and some versions of Internet Explorer allow you
to configure them so that untrusted classes can connect to any host on the network.
4.4.2.3 System access
In 1.1, attempts to redirect the standard input, output, and error streams call the checkExec
method rather than the
checkPermission method. In fact, the
checkPermission method does not
exist at all in 1.1 and earlier releases.
4.4.2.4 Thread access
Thread access policy by appletviewer
and popular browsers in 1.0 and 1.1 is, simply put, very confusing. In 1.1, by default each applet is given an individual thread group, and the threads within that group can
manipulate other threads within that group without respect to any additional hierarchy. The
getThreadGroup method is only present in Java 1.1 and subsequent releases. In Java 1.0 and
browsers built on that release, thread security was generally nonexistent: any thread could manipulate the state of any other thread, and applets werent able to create their own thread groups.
4.4.2.5 Security access
1.1 implements all of the security checks that were listed earlier; in addition, the following methods also call the
checkSecurityAccess method:
Identity.toString ,
Security.getProviders ,
Security.getProvider , and
Security.getProperty . However, since most browsers including Netscape Communicator 4.x and Internet Explorer 4.x do not
implement the standard security package at all, none of these checks are performed in those browsers.
4.5 Summary
In this chapter, weve had an overview of the most commonly known feature of Javas security story: the security manager. The security manager is responsible for arbitrating access to what we normally consider
operating system features −− files, network sockets, printers, etc. The goal of the security manager is to grant access to each class according to the amount of trust the user has in the class. Often, that means granting full
access to trusted classes that is, classes that have been loaded from the filesystem while limiting access when the access is requested from an untrusted class that is, a class that has been loaded from the network.
Although the security manager is the most commonly known feature of Javas security story, its often misunderstood: there is no standard security manager among Java implementations, and Java applications, by
default, have no security manager at all. Even with the popular Java−enabled browsers, the user often has latitude in what protections the security manager will be asked to enforce.
We examined in this chapter all the times when the security manager is asked to make a decision regarding access; such decisions range from the expected file and network access to more esoteric decisions, such as
whether a frame needs a warning banner or what thread group a particular thread should belong to. This gave us a basic understanding of how the security manager is used to enforce a specific policy and the issues
involved when defining such a policy. This knowledge will be used as a basis in the next few chapters when 74
well look at how the security manager is generally implemented. Chapter 4. The Security Manager