Java in a Nutshell, 5th Edition [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Java in a Nutshell, 5th Edition [Electronic resources] - نسخه متنی

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید


6.4. Access Control



As we noted at the beginning of this
chapter, the heart of the Java security architecture is access
control: untrusted code simply must not be granted access to the
sensitive parts of the Java API that would allow it to do malicious
things. As we'll discuss in the following sections,
the Java access control model evolved significantly between Java 1.0
and Java 1.2. Since then, the access control model has been
relatively stable; it has not changed significantly since Java 1.2.
The next sections provide a brief history of the evolution of Java
security as it developed from Java 1.0 to Java 1.2, which marked the
last major changes to the security model.


6.4.1. Java 1.0: The Sandbox




In this first release of Java, all
Java code installed locally on the system is trusted implicitly. All
code downloaded over the network, however, is untrusted and run in a
restricted environment playfully called "the
sandbox." The access control policies of the sandbox
are defined by the currently installed
java.lang.SecurityManager
object. When system code is about to perform a
restricted operation, such as reading a file from the local
filesystem, it first calls an appropriate method (such as
checkRead( )) of the currently installed
SecurityManager object. If untrusted code is
running, the SecurityManager tHRows a
SecurityException that prevents the restricted
operation from taking place.

The most common user of the
SecurityManager class is a Java-enabled web
browser, which installs a SecurityManager object
to allow applets to run without damaging the host system. The precise
details of the security policy are an implementation detail of the
web browser, of course, but applets are typically restricted in the
following ways:

  • An applet cannot read, write, rename, or delete files. It cannot
    query the length or modification date of a file or even check whether
    a given file exists. Similarly, an applet cannot create, list, or
    delete a directory.

  • An applet cannot connect to or accept a connection from any computer
    other than the one it was downloaded from. It cannot use any
    privileged ports (i.e., ports below and including
    port 1024).

  • An applet cannot
    perform system-level functions, such as loading a native library,
    spawning a new process, or exiting the Java interpreter. An applet
    cannot manipulate any threads or thread groups, except for those it
    creates itself. In Java 1.1 and later, applets cannot use the Java
    Reflection API to obtain information about the nonpublic members of
    classes, except for classes that were downloaded with the applet.

  • An applet cannot access certain

    graphics- and GUI-related
    facilities. It cannot initiate a print job or access the system
    clipboard or event queue. In addition, all windows created by an
    applet typically display a prominent visual indicator that they are
    "insecure" to prevent an applet
    from spoofing the appearance of some other application.

  • An applet cannot read certain system properties, notably the
    user.home and user.dir
    properties, that specify the user's home directory
    and current working directory.

  • An applet cannot circumvent these security restrictions by
    registering a new
    SecurityManager object.



6.4.1.1 How the sandbox works

Suppose that an applet (or some other untrusted code running in the
sandbox) attempts to read the contents of the file

/etc/passwd by passing this
filename to the
FileInputStream()
constructor. The programmers who wrote the
FileInputStream class were aware that the class
provides access to a system resource (a file), so use of the class
should therefore be subject to access control. For this reason, they
coded the FileInputStream( ) constructor to use
the
SecurityManager class.

Every time FileInputStream( ) is called, it checks
to see if a SecurityManager object has been
installed. If so, the constructor calls the
checkRead() method of that
SecurityManager object, passing the filename
(

/etc/passwd , in this case) as the sole
argument. The checkRead() method has no return
value; it either returns normally or throws a
SecurityException. If the method returns, the
FileInputStream() constructor simply proceeds with
whatever initialization is necessary and returns. Otherwise, it
allows the SecurityException to propagate to the
caller. When this happens, no FileInputStream
object is created, and the applet does not gain access to the

/etc/passwd file.


6.4.2. Java 1.1: Digitally Signed Classes


Java 1.1 retained the sandbox model
of Java 1.0 but added the java.security package
and its digital signature capabilities. With these capabilities, Java
classes can be digitally signed and verified. Thus, web browsers and
other Java installations can be configured to trust downloaded code
that bears a valid digital signature of a trusted entity. Such code
is treated as if it were installed locally, so it is given full
access to the Java APIs. In this release, the

javakey program
manages keys and digitally signs JAR files of Java code. Although
Java 1.1 added the important ability to trust digitally signed code
that would otherwise be untrusted, it sticks to the basic sandbox
model: trusted code gets full access and untrusted code gets totally
restricted access.


6.4.3. Java 1.2: Permissions and Policies



Java 1.2 introduced substantial access
control features into the Java security architecture. These features
are implemented by classes in the java.security
package. The Policy class is one of the most
important: it defines a Java security policy. A
Policy object maps CodeSource
objects to associated sets of Permission objects.
A CodeSource object represents the source of a
piece of Java code, which includes both the URL of the class file
(and can be a local file) and a list of entities that have applied
their digital signatures to the class file. The
Permission objects associated with a
CodeSource in the Policy define
the permissions that are granted to code from a given source. Various
Java APIs include subclasses of Permission that
represent different types of permissions. These include
java.lang.RuntimePermission,
java.io.FilePermission, and
java.net.SocketPermission, for example.

Under this access control model, the
SecurityManager class continues to be the central
class; access control requests are still made by invoking methods of
a SecurityManager. However, the default
SecurityManager implementation delegates most of
those requests to an AccessController class that
makes access decisions based on the Permission and
Policy architecture.

The Java 1.2 access control architecture
has several important features:

  • Code from different sources can be given different sets of
    permissions. In other words, the architecture supports fine-grained
    levels of trust. Even locally installed code can be treated as
    untrusted or partially untrusted. Under this architecture, only
    system classes and standard extensions run as fully trusted.

  • It is no
    longer necessary to define a custom subclass of
    SecurityManager to define a security policy.
    Policies can be configured by a system administrator by editing a
    text file or using the

    policytool program,
    described in Chapter 8.

  • The architecture is not limited to a
    fixed set of access control methods in the
    SecurityManager class.
    Permission subclasses can be defined easily to
    govern access to system resources (which might be exposed, for
    example, by standard extensions that include native code).



6.4.3.1 How policies and permissions work

Let's

return to the example of an
applet that attempts to create a FileInputStream
to read the file

/etc/passwd . In Java 1.2 and
later, the FileInputStream( ) constructor behaves
exactly the same as it does in Java 1.0 and Java 1.1: it looks to see
if a SecurityManager is installed and, if so,
calls its checkRead() method, passing the name of
the file to be read.

What changed as of Java 1.2 is
the default behavior of the checkRead( ) method.
Unless a program has replaced the default security manager with one
of its own, the default implementation creates a
FilePermission object to represent the access
being requested. This FilePermission object has a

target of
"/etc/passwd" and an

action of
"read." The
checkRead() method passes this
FilePermission object to the static
checkPermission() method of the
java.security.AccessController class.

It is the
AccessController and its
checkPermission( )
method that do the real work of access control as of Java 1.2. The
method determines the CodeSource of each calling
method and uses the current Policy object to
determine the Permission objects associated with
it. With this information, the AccessController
can determine whether read access to the

/etc/passwd file should be allowed.

The Permission class
represents both the permissions granted by a
Policy and the permissions requested by a method
like the FileInputStream() constructor. When
requesting a permission, Java typically uses a
FilePermission (or other
Permission subclass) with a very specific target,
like "/etc/passwd". When granting a
permission, however, a Policy commonly uses a
FilePermission object with a wildcard target, such
as "/etc/*", to represent many
files. One of the key features of a Permission
subclass such as FilePermission is that it defines
an implies() method that can determine whether
permission to read "/etc/*" implies
permission to read
"/etc/passwd".


/ 1191