Executing Programs Securely
Discussions of Java security generally refer to the ability of the Java environment to execute programs (possibly untrusted and malicious programs) securely. This task is accomplished behind the scenes by a number of components of the JVM (Java Virtual Machine): the class loader, the verifier, the security manager and the access controller. These components constitute what is normally referred to as the Java sandbox. They let Java execute an untrusted piece of code while stopping it from performing dangerous actions or subverting the integrity of the Java environment.
A number of Java's language features, such as strong data typing and bounds checking, are a necessity if the run-time environment is to maintain its integrity and stop malicious code from undermining it. The book Securing Java, by Gary McGraw and Edward W. Felten (John Wiley & Sons, January 1999), explains in greater detail the features of Java that enable it to run programs securely.
By default, an untrusted Java program is severely limited as to what it can do. For example, it can't access the file system. This also means a program limited in such a way is not very useful. In Java 2, the Security Manager was changed to accommodate the newly introduced Access Controller. Starting with Java 2, we are given the capability of creating a security policy to selectively allow Java programs to perform certain operations. The policy performs security checks on all Java code (local programs as well as applets), except for those classes found in the class path. Java 2 introduces the concept of a security policy that lets a user or system administrator limit or grant more permissions to certain Java programs or applications. But the default policy is to implement the Java sandbox, in which local Java applications are allowed to do anything, while Java applets running from a Web browser are restricted.
You can create a policy file manually using a text editor, or you can use the PolicyTool that comes with the JDK (Java Development Kit). You assign permissions in the policy based on the code origin--code from a particular code base, code signed by a particular key, or both. The base Java system defines permissions for security, file and sockets.
Note that these access-control checks are performed by the Java run-time environment and are independent of the underlying platform's security checks. Just because a security policy in Java states that a program can open a file does not mean it will be able to do so. Conversely, if a program can bypass a Java policy restriction, the underlying platform may let it access the file if the Java process is executing with high enough privileges.
From a programmer's point of view, you can extend the available permissions by implementing your own for the software you're writing. For more information on how to set up a Java security policy see Sun's "Security in Java SDK 1.2".
Auxiliary APIs
Java also provides a number of auxiliary APIs that are of interest to security programmers. Introduced in Java 1.1, the cryptographic service provider API provides a pluggable API to a number of cryptographic services. These services include digital-signature algorithms, message-digest algorithms, asymmetric key- generation algorithms, keystore creation and management, algorithm-parameter management, algorithm-parameter generation, key factory support to convert among different key representations, certificates, certificate-revocation lists, creation of certificates and certificate-revocation lists, and random-number generation algorithms.
Sun also provides the Java Cryptographic Extensions (JCE, java.sun.com/ products/jce/), which add APIs for encryption, key exchange, symmetric key generation and message authentication code to the base Java APIs. The Java Authentication and Authorization Server (JASS) adds APIs that implement user-based authentication and an access-control mechanism, as well as a Java-based impersonation and single sign-on. Finally, Java Secure Socket Extensions (JSSE) add support for SSL and TLS network-security transport protocols. Read Java Security, by Scott Oaks (O'Reilly & Associates, May 1998), to learn more about the Java cryptographic APIs and the JCE.
The term Java security encompasses a number of different concepts: writing secure programs, executing programs securely, and auxiliary security services. Currently, Java provides relatively weak support for writing secure programs. Its primary feature in this area, array bounds checking, is a basic requirement for executing programs securely, but as the language matures, we can expect to see a more complete and robust security system.
Elias Levy is the CTO and cofounder of SecurityFocus.com. Send your comments on this article to him at aleph1@securityfocus.com.