There was a problem sending you an sms. Check your phone number or try again later.
We've sent a link to the Scribd app. If you didn't receive it, try again.
Aside from platform independence, discussed in the previous chapter, the other major
technical challenge a network-oriented software technology must deal with is security.
Networks, because they allow computers to share data and distribute processing, can
potentially serve as a way to break into a computer system, enabling someone to steal
information, alter or destroy information, or steal computing resources. As a consequence,
connecting a computer to a network raises many security issues.
To address the security concerns raised by networks, Java's architecture comes with an
extensive built- in security model, which has evolved with each major release of the Java
Platform. This chapter gives an overview of the security model built into Java's core
architecture and traces its evolution.
Java's security model is one of the key architectural features that makes it an appropriate
technology for networked environments. Security is important because networks represent a
potential avenue of attack to any computer hooked to them. This concern becomes especially
strong in an environment in which software is downloaded across the network and executed
locally, as is done, for example, with Java applets and Jini service objects. Because the class
files for an applet are automatically downloaded when a user goes to the containing web
page in a browser, it is likely that a user will encounter applets from untrusted sources.
Similarly, the class files for a Jini service object are downloaded from a code base specified
by the service provider when it registers its service with the Jini lookup service. Because Jini
enables spontaneous networking in which users entering a new environment look up and
access locally available services, users of Jini services will likely encounter service objects
from untrusted sources. Without any security, these automatic code download schemes
would be a convenient way to distribute malicious code. Thus, Java's security mechanisms
help make Java suitable for networks because they establish a needed trust in the safety of
executing network-mobile code.
Java's security model is focused on protecting end-users from hostile programs (and bugs in
otherwise benevolent programs) downloaded across a network from untrusted sources. To
accomplish this goal, Java provides a customizable "sandbox" in which untrusted Java
programs can be placed. The sandbox restricts the activities of the untrusted program. The
program can do anything within the boundaries of its sandbox, but can't take any action
outside those boundaries. For example, the original sandbox for untrusted Java applets in
version 1.0 prohibited many activities, including:
Because the sandbox security model imposes strict controls on what untrusted code can and
cannot do, users are able to run untrusted code with relative safety. Unfortunately for the
programmers and users of 1.0 systems, however, the original sandbox was so restrictive, that
well-meaning (but untrusted) code was often unable to do useful work. In version 1.1, the
original sandbox model was augmented with a trust model based on code signing and
authentication. The signing and authentication capability enables the receiving system to
verify that a set of class files (in a JAR file) has been digitally signed (in effect, blessed as
trustworthy) by some entity, and that the class files have not been altered since they were
signed. This enables end users and system administrators to ease the restrictions of the
sandbox for code that has been digitally signed by trusted parties.
Although the security APIs released with version 1.1 include support for authentication, they
don't offer much help in establishing anything more than an all-or-nothing trust policy (in other
words, either code is completely trusted or completely untrusted). Java's next major release,
version 1.2, provided APIs to assist in establishing fine-grained security policies based on
authentication of digitally signed code. The remainder of this chapter will trace the evolution of
Java's security model from the basic sandbox of 1.0, through the code signing and
authentication of 1.1, to the fine-grained access control of 1.2.
In the world of personal computers, you have traditionally had to trust software before you ran
it. You achieved security by being careful only to use software from trusted sources, and by
regularly scanning for viruses just to make sure. Once some software got access to your
system, it had full reign. If it was malicious, it could do a great deal of damage because there
were no restrictions placed on it by the runtime environment of your computer. So in the
traditional security scheme, you tried to prevent malicious code from ever gaining access to
your computer in the first place.
The sandbox security model makes it easier to work with software that comes from sources
you don't fully trust. Instead of approaching security by requiring you to prevent any code you
don't trust from ever making its way onto your computer, the sandbox model allows you to
welcome code from any source. But as code from an untrusted source runs, the sandbox
restricts the code from taking any actions that could possibly harm your system. You don't
need to figure out what code you can and can't trust. You don't need to scan for viruses. The
sandbox itself prevents any viruses or other malicious or buggy code you may invite into your
computer from doing any damage.
If you have a properly skeptical mind, you'll need to be convinced a sandbox has no leaks
before you trust it to protect you. To make sure the sandbox has no leaks, Java's security
model involves every aspect of its architecture. If there were areas in Java's architecture
where security was not considered, a malicious programmer (a "cracker") could likely exploit
those areas to "go around" the sandbox. To understand the sandbox, therefore, you must look
at several different parts of Java's architecture, and understand how they work together.
One of the greatest strengths of Java's sandbox security model is that two of these
components, the class loader and security manager, are customizable. By customizing these
components, you can create a customized security policy for a Java application.
Unfortunately, this customizability doesn't come for free, because the very flexibility of the
architecture creates some risks of its own. Class loaders and security managers are
complicated enough that the mere act of customization can potentially produce errors that
open up security holes.
In each major release of the Java API, changes were made to make the task of creating a
custom security policy less prone to error. The most significant change occurred in version
1.2, which introduced a new and more elaborate architecture for access control. In version
1.0 and 1.1, access control, which involves both the specification of a security policy and the
enforcement of that policy at run time, is the responsibility of an object called the security
manager. To establish a custom policy in 1.0 and 1.1, you have to write your own custom
security manager. In 1.2, you can take advantage of a security manager supplied with the
Java 2 Platform. This ready made security manager allows you to specify a security policy in
an ASCII policy file separate from the program. At runtime, the ready made security manager
enlists the help of a class called the access controller to enforce the security policy specified
in the policy file. The access control infrastructure introduced in 1.2 provides a flexible and
easily customized default implementation of the security manager that should suffice for the
majority of security needs. For backwards compatibility, and to enable parties with special
security needs to override the default functionality provided by the ready made security
manager, version 1.2 applications can still install their own security manager. Using the ready
made made security manager, and the extensive access control infrastructure that comes
with it, is optional.
In Java's sandbox, the class loader architecture is the first line of defense. It is the class
loader, after all, that brings code into the Java virtual machine--code that could be hostile or
buggy. The class loader architecture contributes to Java's sandbox in three ways:
machine maintains for each class loader. Once a Java virtual machine has loaded a class
namedVo l c anointo a particular name-space, for example, it is impossible to load a different
class namedVo l c anointo that same name-space. You can load multipleVolc ano classes
into a Java virtual machine, however, because you can create multiple name-spaces inside a
Java application by creating multiple class loaders. If you create three separate name-spaces
(one for each of three class loaders) in a running Java application, then, by loading one
Name-spaces contribute to security because you can in effect place a shield between classes
loaded into different name-spaces. Inside the Java virtual machine, classes in the same
name-space can interact with one another directly. Classes in different name-spaces,
however, can't even detect each other's presence unless you explicitly provide a mechanism
that allows them to interact. If a malicious class, once loaded, had guaranteed access to
every other class currently loaded by the virtual machine, that class could potentially learn
things it shouldn't know or interfere with the proper execution of your program.
Figure 3-1 shows the name-spaces associated with two class loaders, both of which have
loaded a type namedVo l c a n o. Each name in a name space is associated with the type data
in the method area that defines the type with that name. Figure 3-1 shows arrows from the
names in the name- spaces to the types in the method area that define the type. The class
loader on the left, which is shown dark gray, has loaded the two dark gray types named
Now bringing you back...
Does that email address look wrong? Try again with a different email.