Securing Tomcats Permissions

Securing Tomcat’s Permissions

Configuring your file system for maximum security is an important part of securing your Tomcat deployment, but it’s only half of the picture. By using Java’s security manager architecture, you can restrict those features of the Java language that Tomcat is able to access.

The Java Security Manager

The Java security manager architecture allows you to impose fine-grained security restrictions to all Java applications. This security architecture is turned off by default, but you can turn it on at any time. In the following sections you’ll see the security manager architecture in general terms and then look at how this architecture specifically applies to Tomcat.

Overview of the Security Manager

The security manager architecture works on the notion of permissions (just as the file system does). Once the security manager is turned on, applications must have explicit permission to perform certain security-sensitive tasks, such as creating a custom class loader or opening a socket to servers.

To use the security manager effectively, it’s therefore necessary to know how applications can be given permissions and what the possible permissions are.

Granting Permissions to Applications

Policy files are the mechanism that the security manager uses to grant permissions to applications. Policy files are nothing more than simple text files composed of individual actions that applications can perform.

A policy file is composed of grant entries, as shown in Listing 12-1.

Listing 12-1: A Policy File

image from book
 // first grant entry  grant {    permission java.lang.RuntimePermission "stopThread";  }  // second grant entry  grant codeBase "file:${java.home}/lib/ext/*" {    permission java.security.AllPermission;  }; 
image from book

The first grant entry demonstrates the simplicity of the syntax. It grants all applications the ability to access the deprecated Thread.stop() method.

The second grant entry illustrates that code in specific locations can also be granted permissions. This is useful when you want to extend permissions to certain trusted code while denying permissions to all other code. In this case, all code in the JAVA_HOME/lib/ext directory is granted all permissions, which disables the security manager architecture for that code.

Writing Grant Entries

Each grant entry must be composed of the following syntax:

 grant codeBase "URL" {    // this is a comment    permission permission_class_name "target_name", "action";    ...  }; 

Note that comments in policy files must begin with // on each line. As you saw in the first grant entry, the codeBase attribute is optional. codeBase specifies a URL to which all the permissions should apply. Table 12-9 describes the syntax.

Table 12-9: The codeBase Attribute’s Syntax

codeBase Example

Description

file:/C:/myapp/

This assigns the permissions in the grant block to the c:\myapp directory. Note that the slash (/) indicates that only class files in the directory will receive the permissions, not any JAR files or subdirectories.

http://java.sun.com/*

All code from the specified URL will be granted the permissions. In this case, the /* at the end of the URL indicates that all class files and JAR files will be assigned the permissions, but not any subdirectories.

file:/matthewm/-

All code in the /matthewm directory will be granted the permissions in the grant block. The /- indicates that all class files and JAR files in the directory and its subdirectories will be assigned the permissions.

Within the grant block, one or more permissions can be assigned. A permission consists of a permission class name and, in some cases, an additional target that identifies a specific permission within the permission class. Some permission targets can additionally take parameters, called actions. Listing 12-2 shows examples of permissions.

Listing 12-2: Example Permissions

image from book
 grant {    // allows applications to listen on all ports    permission java.net.SocketPermission "localhost", "listen";    // allows applications to read the "java.version" property    permission java.util.PropertyPermission "java.version", "read";  } 
image from book

Special classes that ultimately inherit from the abstract class java.security.Permission define permissions. Most permission classes define special targets that represent a security permission that can be turned on and off.

Nineteen different permission classes offer control over various permissions. Table 12-10 describes these classes to demonstrate what’s possible with permissions but doesn’t provide an extensive listing of the permission targets. You can view the complete list of permission classes and their targets at http://java.sun.com/j2se/1.4/docs/guide/security/permissions.html.

Table 12-10: Permissions for Policy Files

Permission Class

Description

java.security.AllPermission

By granting this permission, all other permissions are also granted. Granting this permission is the same as disabling the security manager for the affected code.

java.security.SecurityPermission

Allows programmatic access to various security features of the Java language.

java.security.UnresolvedPermission

This permission class isn’t defined in policy files; rather, it’s used as a placeholder for when a policy file makes reference to a user-defined permission class that hadn’t been loaded at the time of processing the policy file. This permission is relevant only to those interacting with the security manager system programmatically at run time.

java.awt.AWTPermission

Controls various AWT permissions.

java.io.FilePermission

Restricts read, write, execute, and delete access to files in specified paths.

java.io.SerializablePermission

Allows serialization permissions.

java.lang.reflect.ReflectPermission

Allows applications to circumvent the public and private mechanism’s access checks and reflectively access any method.

java.lang.RuntimePermission

Allows access to key runtime features, such as creating class loaders, exiting the VM, and reassigning stdin, stdout, and stderr.

java.net.NetPermission

Allows various network permissions.

java.net.SocketPermission

Allows incoming socket connections, outgoing connections, listening on ports, and resolving hostnames. These permissions can be defined on specific hostnames and port combinations.

java.sql.SQLPermission

While this sounds intriguing, don’t get too excited; it controls only a single permission: setting the JDBC log output writer. This file is considered sensitive because it may contain usernames and passwords.

java.util.PropertyPermission

Controls whether properties can be read from or written to.

java.util.logging.LoggingPermission

Allows the ability to configure the logging system.

javax.net.ssl.SSLPermission

Allows the ability to access SSL-related network functionality.

javax.security.auth.AuthPermission

Controls authentication permissions.

javax.security.auth.PrivateCredentialPermission

Controls various security permissions.

javax.security.auth.kerberos.DelegationPermission

Controls various security permissions related to the Kerberos protocol.

javax.security.auth.kerberos.ServicePermission

Controls various security permissions related to the Kerberos protocol.

javax.sound.sampled.AudioPermission

Controls access to the sound system.

Enabling the Security Manager System

You can enable the security manager system by passing the -Djava.security.manager parameter to the JVM at startup, as follows:

 > java -Djava.security.manager MyClass 

By default, Java looks for JAVA_HOME/lib/security/java.policy to determine what permissions to grant when the security manager is turned on. For more information on enabling the security manager and using your own policy files, see http://java.sun.com/j2se/1.4/docs/guide/security/PolicyFiles.html.

Using the Security Manager with Tomcat

Now that I’ve covered the basics of the security manager system, it’s time to talk about how to use it with Tomcat.

Enabling Tomcat’s Security Manager

The preferred way to start Tomcat with the security manager enabled on Unix systems is the following:

 $ $CATALINA_HOME/bin/catalina.sh start -security 

On Windows systems, you’d issue this command:

 > %CATALINA_HOME%\bin\catalina start -security 

Tomcat’s Policy File

Tomcat uses the CATALINA_HOME/conf/catalina.policy file to determine its own permissions and those of its Web applications. Listing 12-3, Listing 12-4, and Listing 12-5 show this file in full. Note that it’s divided into three sections: system code permissions, Catalina code permissions, and Web application code permissions.

Listing 12-3: The System Code Permissions from Tomcat’s Default Policy File

image from book
 // ========== SYSTEM CODE PERMISSIONS  =========================================  // These permissions apply to javac  grant codeBase "file:${java.home}/lib/-" {          permission java.security.AllPermission;  };  // These permissions apply to all shared system extensions  grant codeBase "file:${java.home}/jre/lib/ext/-" {          permission java.security.AllPermission;  };  // These permissions apply to javac when ${java.home] points at $JAVA_HOME/jre  grant codeBase "file:${java.home}/../lib/-" {          permission java.security.AllPermission;  };  // These permissions apply to all shared system extensions when  // ${java.home} points at $JAVA_HOME/jre  grant codeBase "file:${java.home}/lib/ext/-" {          permission java.security.AllPermission;  }; 
image from book

Listing 12-4: The Catalina Code Permissions from Tomcat’s Default Policy File

image from book
 // ======== CATALINA CODE PERMISSIONS  =======================================  // These permissions apply to the launcher code  grant codeBase "file:${catalina.home}/bin/commons-launcher.jar" {          permission java.security.AllPermission;  };  // These permissions apply to the daemon code  grant codeBase "file:${catalina.home}/bin/commons-daemon.jar" {          permission java.security.AllPermission;  };  // These permissions apply to the commons-logging API  grant codeBase "file:${catalina.home}/bin/commons-logging-api.jar" {          permission java.security.AllPermission;  };  // These permissions apply to the server startup code  grant codeBase "file:${catalina.home}/bin/bootstrap.jar" {          permission java.security.AllPermission;  };  // These permissions apply to the JMX server  grant codeBase "file:${catalina.home}/bin/jmx.jar" {          permission java.security.AllPermission;  };  // These permissions apply to the servlet API classes  // and those that are shared across all class loaders  // located in the "common" directory  grant codeBase "file:${catalina.home}/common/-" {          permission java.security.AllPermission;  };  // These permissions apply to the container's core code, plus any additional  // libraries installed in the "server" directory  grant codeBase "file:${catalina.home}/server/-" {          permission java.security.AllPermission;  }; 
image from book

Listing 12-5: The Web Application Permissions from Tomcat’s Default Policy File

image from book
 // ======== WEB APPLICATION PERMISSIONS  ====================================  // These permissions are granted by default to all Web applications  // In addition, a Web application will be given a read FilePermission  // and JndiPermission for all files and directories in its document root.  grant {      // Required for JNDI lookup of named JDBC DataSources and      // javamail named MimePart DataSource used to send mail      permission java.util.PropertyPermission "java.home", "read";      permission java.util.PropertyPermission "java.naming.*", "read";      permission java.util.PropertyPermission "javax.sql.*", "read";      // OS Specific properties to allow read access      permission java.util.PropertyPermission "os.name", "read";      permission java.util.PropertyPermission "os.version", "read";      permission java.util.PropertyPermission "os.arch", "read";      permission java.util.PropertyPermission "file.separator", "read";      permission java.util.PropertyPermission "path.separator", "read";      permission java.util.PropertyPermission "line.separator", "read";      // JVM properties to allow read access      permission java.util.PropertyPermission "java.version", "read";      permission java.util.PropertyPermission "java.vendor", "read";      permission java.util.PropertyPermission "java.vendor.url", "read";      permission java.util.PropertyPermission "java.class.version", "read";      permission java.util.PropertyPermission "java.specification.version", "read";      permission java.util.PropertyPermission "java.specification.vendor", "read";      permission java.util.PropertyPermission "java.specification.name", "read";      permission java.util.PropertyPermission "java.vm.specification.version", "read";      permission java.util.PropertyPermission "java.vm.specification.vendor", "read";      permission java.util.PropertyPermission "java.vm.specification.name", "read";      permission java.util.PropertyPermission "java.vm.version", "read";      permission java.util.PropertyPermission "java.vm.vendor", "read";      permission java.util.PropertyPermission "java.vm.name", "read";      // Required for OpenJMX      permission java.lang.RuntimePermission "getAttribute";      // Allow read of JAXP compliant XML parser debug      permission java.util.PropertyPermission "jaxp.debug", "read";      // Precompiled JSPs need access to this package.      permission java.lang.RuntimePermission  "accessClassInPackage.org.apache.jasper.runtime";      permission java.lang.RuntimePermission  "accessClassInPackage.org.apache.jasper.runtime.*";  }; 
image from book

Tomcat’s policy file grants all permissions to javac, which compiles JSP pages into servlets, and it also grants all permissions to any Java standard extensions. Four grant lines are used instead of two to deal with multiple path possibilities. Note that you may need to add additional grants to this section if your JVM uses different paths for its standard extensions (Mac OS X needs additional grants, for example) and you’re actually putting JARs or classes in those paths.

Note that Catalina grants all permissions to the following:

  • Tomcat’s startup classes (CATALINA_HOME/bin/bootstrap.jar)

  • The common class loader files (CATALINA_HOME/common/lib and CATALINA_HOME/common/classes)

  • The server class loader files (CATALINA_HOME/server/lib and CATALINA_HOME/server/classes)

Tomcat allows read access to various system properties. Note also the following grant:

     permission java.lang.RuntimePermission  "accessClassInPackage.org.apache.jasper.runtime"; 

The accessClassInPackage.* target of RuntimePermission allows classes to see other classes to which they wouldn’t normally have access. In this case, Tomcat is giving all Web applications access to the org.apache.jasper.runtime.* package.

Recommended Security Manager Practices

Now that you know how to turn on the security manager with Tomcat and where Tomcat stores its policy file, you can look at recommended practices for granting permissions to your applications.

Use the Security Manager

If you don’t turn on Tomcat’s security manager, any JSP page or class file is free to perform any action it likes. This includes opening unauthorized connections to other network hosts, destroying your file system, or even abnormally terminating Tomcat by issuing the System.exit() command.

To maintain a secure Tomcat installation, you should assume that at some point a hacker will be able to deploy malicious code into one of Tomcat’s Web applications. By turning the security manager on, you gain explicit control over what Web applications are allowed to do.

Regulating Common Code

Placing code into Tomcat’s common class loader directories (CATALINA_HOME/common/classes and CATALINA_HOME/common/lib) is a good way to share common libraries among Web applications. However, because of Tomcat’s liberal permission grants for this class loader (all permissions are granted), you may want to think twice before you make a habit out of placing code in this class loader.

You must do either of the following:

  • Ensure that all code placed in this class loader is trusted.

  • Place the code in the shared class loader. This class loader isn’t covered by the security manager by default and is therefore restricted in its actions.

Example Grants

As mentioned, turning the security manager on gives you complete control over what Web applications are allowed to do. The flip side of this security coin is that Web applications will find themselves unable to do some things that they may have taken for granted before. Consider the following tasks that are unauthorized with Tomcat’s default policy configuration:

  • Creating a class loader

  • Accessing a database via a socket (for example, the MySQL JDBC driver establishing a connection with a MySQL database)

  • Sending an e-mail via the JavaMail API

  • Reading or writing to files outside a Web application’s directory

Creating a Class Loader

Listing 12-6 shows how to give a specific Web application the ability to create a class loader.

Listing 12-6: Allowing Class Loader Creation

image from book
  grant codeBase "file:${catalina.home}/webapps/tomcatBook/WEB-INF/-" {    permission java.lang.RuntimePermission "createClassLoader";  }; 
image from book

This is an extremely dangerous permission to grant. Applications that can instantiate their own class loaders can, by definition, load their own classes. As mentioned earlier, malicious classes could then be used to compromise your system in a number of ways.

Opening Socket Connections to Databases

Listing 12-7 shows how to allow all Web applications access to a specific database running on the host db.server.com on port 54321.

Listing 12-7: Allowing a Database Connection

image from book
 grant codeBase "file:${catalina.home}/webapps/-" {    permission java.net.SocketPermission "db.server.com:54321", "connect";  }; 
image from book

This example allows all code in all Web applications to connect to db.server.com:54321. If this is too much of a security risk for you, you have a few alternative options.

First, explicitly assign permission to each Web application’s JDBC driver individually, as shown in Listing 12-8.

Listing 12-8: Enabling a Web Application to Make a Database Connection

image from book
 grant codeBase "file:${catalina.home}/webapps/tomcatBook/WEB-INF/lib/JDBC.jar" {    permission java.net.SocketPermission "db.server.com:54321", "connect";  }; 
image from book

Second, place the JDBC driver into the common class loader, which has all permissions granted to it. This means the driver can access the database, but the Web application can’t.

Sending an E-mail with JavaMail

To send e-mail, Web applications need access to port 25 on an SMTP server. Listing 12-9 shows how to grant this permission to all classes in a Web application.

Listing 12-9: Allowing Access to an SMTP Server

image from book
 grant codeBase "file:${catalina.home}/webapps/myWebApp/WEB-INF/classes/-" {    permission java.net.SocketPermission "mail.server.com:25", "connect";  }; 
image from book

Reading or Writing to Files Outside a Web Application’s Directory

If you want to use your operating system to control file access, rather than Java’s permissions, you can give your Web applications free rein once again, as in Listing 12-10.

Listing 12-10: Allowing Access to All Files

image from book
 grant {    java.io.FilePermission "<<ALL FILES>>", "read,write,execute,delete";  }; 
image from book

If you don’t grant at least some file permissions to your Web application, your Web applications will be shut out from accessing your file system. You should still secure it with your operating system’s file permissions, because, even though your Web applications may be shut out, Tomcat itself has full permissions, and should a malicious hacker modify Tomcat somehow, they could still access your file system.



Pro Jakarta Tomcat 5
Pro Apache Tomcat 5/5.5 (Experts Voice in Java)
ISBN: 1590593316
EAN: 2147483647
Year: 2004
Pages: 94

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net