• No results found

.

Quick Quiz

73

.

In Brief

74

7

Manipulating Java

Security

“An expert is one who knows more and more about less and less until he knows absolutely everything about nothing.”

Murphy’s Technology Laws

Java Security Overview

From the beginning Java was designed to be secure. Security includes language features such as array index range checks, bytecode verification, and controlled access to critical system resources such as files and user informa- tion. At the beginning the security model assumed that all locally installed classes should be granted access to system resources and that all bytecode downloaded via the network should be restricted from sensitive information and operations. As Java matured, the distinction between the local and remote classes somewhat blurred. Application servers and Web servers rely on the security model to ensure that one component, such as a Web application, does not violate another. Signed applets allow downloaded code to access local files, the clipboard, and system proper- ties.

Various core classes at runtime use the security framework to check whether the caller should be allowed to perform the requested operation. At the center of the security model is an instance of java.lang.SecurityManagerthat acts as a facade for the java.securitypackage. Java uses the concept of a permission to represent access to system information or a resource. For example,

PropertyPermissionrepresents access to system properties. Before executing the method logic, core classes use the security manager to check whether the caller is granted the appropriate permissions. An easy way to understand how the mechanism works is to look at the implementation of the System.setProperty()method, shown in Listing 7.1.

LISTING 7.1 System.setProperty

public static String setProperty(String key, String value) { if (key == null) {

throw new NullPointerException(“key can’t be null”); }

if (key.equals(“”)) {

throw new IllegalArgumentException(“key can’t be empty”); }

if (security != null)

security.checkPermission(new PropertyPermission(key, “write”)); return (String) props.setProperty(key, value);

}

The implementation first obtains the system security manager. If one is installed and the parameters are valid, it then uses the security manager to verify that PropertyPermissionto write into the given key is granted. The security manager’s checkPermissionmethod throws a

SecurityExceptionexception if the permission is not granted. The system property is set to the new value only if checkPermissionreturns successfully. Table 7.1 lists the operations governed by the security manager.

TA B L E 7 . 1

Operations Protected by the Security Manager

TYPE PROTECTED OPERATIONS

System Access packages

Access member variables and methods of a class Load native libraries

Exit the system Start and stop threads Create custom class loaders Input, Output, Network Create, remove, read, and write files

Traverse directories Create sockets

Load classes from a network URL AWT/Swing Access the clipboard

Access the system event queue

Display windows without a warning message Get a print job

The information on which permissions are granted to which classes is stored in Java policy files. The systemwide java.policyfile is loaded first from the ${java.home}/lib/security directory, where ${java.home}is the JRE installation directory. If it exists, the

${user.home}/.java.policyfile is loaded next. A custom Java policy file can be specified at the command line using the -Djava.security.policyparameter. A detailed discussion of Java security and permissions can be found at http://java.sun.com/j2se/1.3/docs/ guide/security/permissions.html.

Java security includes APIs for encryption (JCE), authentication and authorization (JAAS), secure sockets support (JSSE), and many others. These additional APIs provide powerful means of protecting the information, but they are not used directly in a typical application. We are going to focus on the security features an application developer is most likely to face.

Bypassing Security Checks

From the perspective of this book, we are mostly interested in bypassing the security checks performed by Java runtime. The three configuration scenarios that determine the strictness of the security model are as follows:

n The security manager is not installed.

n The security manager is installed with a default policy. n The security manager is installed with a custom policy.

71

Bypassing Security Checks

We were planning to use a third-party deployment technology to roll out our Swing application to thousands of user desktops. The product we were going to use supported automatic updates, which required the application to be started by the product’s launcher rather than as a standalone application. To implement the automatic update via HTTP, the product was installing its own HTTP handler that conflicted with the SSL-enabled HTTP handler used by our application. Java does not support the dynamic switching of protocol handlers because it stores and reuses the implementa- tion instances from a private cache. The only way to get around the problem was to forcefully clear the cache upon application startup. We used the technique for accessing private members

described in Chapter 4, “Hacking Non-Public Methods and Variables of a Class,” which requires a security manager and a custom policy file. We shipped the policy file, allowing unrestricted access to class members via the reflection API with our application, and after clearing the cache at the startup, we got the product to coexist with our code.