The Java Security Landscape

Architects, developers, and IT managers must take collective responsibility for creating secure solutions. Exploit Java's language- and enterprise-level security features to build a secure environment.

The Java Security Landscape
Understand the myriad of security domains to create secure applications.
by Tarak Modi

November 1, 2004

"One in three firms suffer hacking attempts," reported vnunet.com on March 23, 2004, based on a survey conducted by PricewaterhouseCoopers. Unfortunately, this story is not unique and not really news. We are all aware of the numerous hackers just waiting to get into your system. For some hackers, it's merely the thrill of breaking in. Others have more malicious intent.

Regardless of the hackers' intentions, as software professionals—whether it be as architects, developers, or managers—it is our collective responsibility to create secure, hack-proof (or hacker unfriendly) solutions. This article explores application security issues and offers a high-level discussion about how and where Java fits into the mix so you can capitalize on its security features to build a secure architecture.

Exploring System Security
System security is a complex topic and involves many interrelated domains. For example, consider a computer that sits in a public area for public access. No matter how many bells and whistles you put on it, it's in danger of being hacked. In other words, this is not the computer you want to do your annual taxes on. On the other hand, consider a computer in a bank vault with no disk drives (floppy, CD, or DVD) or network connections (not even a network adapter card). Hacking this computer would be an incredible feat. Physical security is just one domain of computer security.

Another domain is procedural/operational, which covers how the security-related information is maintained. For example, even the most creative password is vulnerable if it is written down on a piece of paper and taped under your keyboard. Finally, even the government has an important role in securing your system by enacting, implementing, and enforcing the proper legistations related to punishing hackers.

When most people think about system security, they think of components such as firewalls and proxy servers, or protocols such as Secure Sockets Layer (SSL). While these are important to security, they do not always guarantee system security. The primary function of these is to keep outsiders where they belong—outside. Statistics have shown again and again that most hacking attempts occur from the inside. To protect against these types of attacks, applications must be architected with security in mind.

Security in the Java Platform
The Java platform is a popular choice for creating enterprise applications. One of the key reasons behind its mass popularity is that Java was created with security in mind and marketed as a "secure" language. While security flaws have been found in the Java implementations from various vendors (such as Microsoft), the architectural pieces within Java for providing security have survived the test of time. The Java platform provides security at two levels: the language level and the enterprise level.

Language Security Features
As mentioned above, Java was created with security in mind and has matured over the years. The following components form Java's language-level security:

The Java Classloader
Java programs are written as a collection of source code files, each with one or more class definitions. These are then compiled into bytecode (.class) files and might be packaged into a Java Archive (JAR) file. Java code is executed in a Java Virtual Machine (JVM), which is typically written in a language such as C for a specific platform such as Windows or Solaris. The JVM loads the bytecode during run time using a series/chain of classloaders. To ensure that the bytecode has not been tampered with between the time it was initially created (during compilation) and to the time it was later loaded for execution, the classloader checks the loaded bytecode to ensure that:

  • The loaded bytecode doesn't forge pointers.
  • The loaded bytecode doesn't violate access restrictions.
  • The loaded bytecode accesses objects as what they are (for example, InputStream objects are always used as InputStreams and never as anything else).

This process is known as "bytecode verification," and it critical in ensuring the safety of executing code. The classloader is the gatekeeper of Java security, so Java takes precautions to ensure that the classloader mechanism is not compromised. These include the following two safeguards:

  • Java applications need special permissions to create and install new classloaders (beyond what the JVM provides) within the JVM.
  • All classloaders must delegate to their parent to ensure that previously loaded classes, such as core Java API classes, are not replaced by malicious code.

The classloader relies heavily on two other pieces of the Java security architecture, both of which I will discuss next.

The Security Manager
Prior to Java 1.2, the security manager was responsible for enforcing all security policies within the JVM. These policies were enforced based on measures such as current class depth or current classloader depth. These methods have now been deprecated. With the introduction of version 1.2, the security manager delegates much of the security policy enforcement work to a new component called the access controller, which allows for a much richer and more flexible security policy.

The Access Controller
The introduction of the access controller has led to the introduction of several new concepts within Java such as a permission, policy, code source, and protection domain. Each Java 1.2 application is associated with a code source that determines the origin of the code. Based upon this code source, the application is granted (or denied) a set of permissions. A policy encapsulates the associations (or mappings) between each code source and its permission sets. Each such association/mapping is called a protection domain. Thus, a policy is a collection of protection domains.

Ultimately, the access controller serves three primary purposes:

  • It decides whether an access to a critical system resource is allowed or denied, based on the security policy currently in effect.
  • It allows marking code as being "privileged," thus affecting subsequent access determinations.
  • It obtains a "snapshot" of the current calling context so access-control decisions from a different context can be made with respect to the saved context.

Enterprise Security Features
So far I have presented Java's built-in security features. All Java applications inherit these by default, although some applications might leverage these better than others. The Java platform also offers other APIs/facilities to provide an overall security solution for enterprise applications. I will list and briefly describe these here:

Java Cryptography Extension (JCE)
JCE is a set of packages that provides a framework and implementations for encryption, key generation and key agreement, and Message Authentication Code (MAC) algorithms. JCE supports multiple types of encryption that includes symmetric, asymmetric, block, and stream ciphers. Prior to Java 1.4, JCE was an optional package, but is now a standard part of the Java platform.

Java Secure Sockets Extension (JSSE)
JSSE is a set of packages that enable secure Internet communications. It implements a Java technology version of SSL and Transport Layer Security (TLS) protocols. It includes functionality for data encryption, server authentication, message integrity, and optional client authentication. As with JCE, JSSE has been integrated within the Java platform since version 1.4.

Java Naming and Directory Interface (JNDI)
JNDI is an API specified in Java technology that provides naming and directory functionality to applications written in the Java programming language. It is designed especially for the Java platform using Java's object model. Using JNDI, applications based on Java technology can store and retrieve named Java objects of any type. Each object in the JNDI directory can be secured. This means that users accessing a reference to such an object would need to provide their credentials, which would be validated by the JNDI implementation. Java application servers use JNDI extensively for storing references to Enterprise JavaBean (EJB) instances, Java Message Service (JMS) queues, and Java Database Connectivity (JDBC) data sources (database connections).

Java Authentication and Authorization Specification (JAAS)
Prior to JAAS's introduction, Java's built-in security was based on where the JVM's code originated. No consideration was given to "who" executed the code. But the "who" in code execution is an important consideration because you might want to control the program's capabilities based on that "who." JAAS extends Java's existing security infrastructure to overcome that shortcoming.

The JAAS authentication component provides the ability to determine reliably and securely who is currently executing Java code, regardless of whether the code is running as an application, an applet, a bean, or a servlet. The JAAS authorization component supplements the existing Java 2 security framework by providing the means to restrict the executing Java code from performing sensitive tasks depending on not only its origin, but on the authenticated user as well. JAAS authentication is performed in a pluggable fashion, which permits Java applications to remain independent from underlying authentication technologies. Therefore, new or updated authentication technologies can be plugged under an application without requiring modifications to the application itself. Finally, as with JCE and JSSE, JAAS has been integrated within the Java platform since version 1.4. Read more about JAAS in "All That JAAS" (Java Pro).

Web Application Security
Web application security builds upon core Java language security to provide an additional layer of security to presentation-tier components. Web application security is available in two modes: declarative and programmatic. Both modes allow the association of "roles" to Web resources such as servlets and JavaServer Pages (JSP). A role is similar to a group in your computer's operating system (such as Windows XP), which means a role is simply a collection of users. In an operating system, groups allow you to control access to system resources at a macro level. For example, you might allow all users within the Human Resources group to access a payroll spreadsheet. In declarative security, the association between roles and Web resources is made in the Web deployment descriptor (web.xml). Programmatic security enforces the associations between roles and Web resources from within the Web resource itself by using method calls (getRemoteUser, getCallerPrincipal, and isCallerInRole) specified by the Java servlet specification.

EJB Security
Similar to Web application security, EJB security builds upon core Java language security to provide an additional layer of security to business objects. Also similar to Web application security, EJB security is available in declarative and programmatic modes. Both modes allow the association of roles to methods in the EJB. In declarative security, the role/method association is made in the application deployment descriptor (ejb-jar.xml) and in an application server-specific deployment descriptor. Programmatic security enforces the associations using method calls (getCallerPrincipal and isCallerInRole) specified by the EJB specification.

The Liberty Alliance (and Web Services Security)
The Liberty Alliance project was started in September 2001 to establish an open standard for federated identity management and related services. This project's importance in the context of this article is that Sun Microsystems is a founding member of the Liberty Alliance, which now includes 13 other companies such as American Express, HP, Nokia, Sony, GM, and others on its management board and numerous other member companies at the sponsor, associate, and affiliate levels.

The alliance's primary output to date is a federation network identity architecture and specification that offers a technology blueprint for organizations that want to create innovative identity-based Web services. This architecture's three fundamental building blocks are:

  • Users interested in consuming Web-based services are called principals and encompass both human and system users.
  • Service providers provide a set of services (such as airline ticket booking) that a principal would want to consume.
  • Identity providers provide credentials to the service providers that authenticate the principal.

The architecture also describes a process that allows principals to single sign-on (SSO) and single logoff at the service providers. SSO allows a user to sign-on once at a Liberty-enabled site (or service provider) and to be seamlessly signed on when navigating to another Liberty-enabled site without the need to authenticate again. Single logout provides synchronized session logout functionality across all sessions authenticated by a particular identity provider.

Additionally, the architecture defines the concept of a circle of trust, which is a federation of service providers and identity providers that have business relationships based on Liberty architecture and operational agreements and with whom users can transact business in a secure and apparently seamless environment. Finally, the architecture describes the use of the Security Assertion Markup Language (SAML), an OASIS standard, for communicating security-related information (called assertions) between service and identity providers.

In this article, I started by providing an overview of the myriad of issues surrounding system security. I then explored, at a high level, the various pieces of this puzzle the Java platform brings to the table to assist in creating a secure architecture. Remember, there's more to system security than using Java, putting a firewall and a proxy server in place, and using SSL for communication. Rather, a secure application is one architected with security in mind.

About the Author
Tarak Modi is a senior specialist with North Highland, a management and technology consulting company. His professional experience includes working with COM, MTS, COM+, .NET, J2EE, and CORBA. He is a coauthor of Professional Java Web Services (Wrox Press, 2002). Visit his personal Web site at http://www.tekNirvana.com.