# Using the Java SecurityManager with Tomcat

- Why use a SecurityManager?
- System Requirements
- Precautions
- Types of Permissions
- Tomcat Custom Permissions
- Configuring Tomcat for use with a SecurityManager
- Starting Tomcat with a SecurityManager
- Trouble shooting catalina.policy configuration and Security Violations
- What happens when the SecurityManager detects a Security violation?

### Why use a SecurityManager?

The Java SecurityManager is what allows a web browser to run an applet in its own sandbox to prevent untrusted code from accessing files on the local system, connecting to a host other than the one the applet was loaded from, etc.

In the same way the SecurityManager protects you from an untrusted applet running in your browser, use of a SecurityManager while running Tomcat can protect your server from trojan servlets, JSP's, JSP beans, and tag libraries. Or even inadvertent mistakes.

Imagine if someone who is authorized to publish JSP's on your site invadvertently included the following in their JSP:

>     <% System.exit(1); %>

Every time that JSP was executed by Tomcat, Tomcat would exit.

Using the Java SecurityManager is just one more line of defense a system administrator can use to keep the server secure and reliable.

### System Requirements

Use of the SecurityManager requires a JVM that supports JDK 1.2.

### Precautions

Implementation of a SecurityManager in Tomcat has not been fully tested or had a security audit. Make sure that you are satisfied with your SecurityManager configuration before allowing untrusted users to publish web applications, JSP's, servlets, beans, or tag libraries.

Still, running with a SecurityManager is definitely better than running without one.

### Types of Permissions

Permission classes are used to define what Permissions a class loaded by Tomcat will have. There are a number of Permission classes as part of the JDK and you can even create your own Permission class for use in your own web applications.

This is just a short summary of the System SecurityManager Permission classes applicable to Tomcat. Please refer to http://java.sun.com/security/ for more information on using the Java SecurityManager and the below Permissions.

java.util.PropertyPermission
Controls read/write access to JVM properties such as java.home.

java.lang.RuntimePermission
Controls use of some System/Runtime functions like exit() and exec().

java.io.FilePermission
Controls read/write/execute access to files and directories.

java.net.SocketPermission
Controls use of network sockets.

java.net.NetPermission
Controls use of multicast network connections.

java.lang.reflect.ReflectPermission
Controls use of reflection to do class introspection.

java.security.SecurityPermission
Controls access to Security methods.

java.security.AllPermission
Allows access to all permissions, just as if you were running Tomcat without a SecurityManager.

## Tomcat Custom Permissions

Tomcat provides a custom permission class called org.apache.naming.JndiPermission, this permission controls read access to JNDI named file based resources. The permission name is the JNDI name and there are no actions. A trailing '*' can be used to do wild card pattern matching for a JNDI named file resource when granting permission.

Example:

`permission org.apache.naming.JndiPermission "jndi://localhost/examples/*";`
``

### Configuring Tomcat for use with a SecurityManager

catalina.policy

The security policies implemented by the Java SecurityManager are configured in the `catalina.policy` file located in the tomcat `conf` directory. The `catalina.policy` file replaces any system `java.policy` file. The `catalina.policy` file can be edited by hand or you can use the policytoolapplication that comes with Java 1.2.

Entries in the `catalina.policy` file use the standard `java.policy` file format as follows:

    // Example policy file entry

    grant [signedBy <signer> [,codeBase <code source>] {
        permission <class> [<name> [, <action list>]];
    };

The signedBy and codeBase entries are optional when granting permissions. Comment lines begin with `//` and end at a new line.

The codeBase is in the form of a URL and for a file URL can use the ${java.home} and ${catalina.home} properties which are expanded out to the directory paths defined for them.

Default catalina.policy file

    // ============================================================================
    // catalina.corepolicy - Security Policy Permissions for Tomcat 4.0
    //
    // This file contains a default set of security policies to be enforced (by the
    // JVM) when Catalina is executed with the "-security" option.  In addition
    // to the permissions granted here, the following additional permissions are
    // granted to the codebase specific to each web application:
    //
    // * Read access to the document root directory
    //
    // $Id: tomcat-security.html,v 1.3 2001/06/29 18:01:37 glenn Exp $
    // ============================================================================

    // ========== 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;
    };

    // ========== CATALINA CODE PERMISSIONS =======================================

    // 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 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;
    };

    // These permissions apply to the jasper page compiler
    // located in the "jasper" directory.
    grant codeBase "file:${catalina.home}/jasper/-" {
      permission java.security.AllPermission;
    };

    // These permissions apply to shared web application libraries
    // including the Jasper runtime library installed in the "lib" directory
    grant codeBase "file:${catalina.home}/lib/-" {
      permission java.security.AllPermission;
    };

    // These permissions apply to shared web application classes
    // located in the "classes" directory
    grant codeBase "file:${catalina.home}/classes/-" {
      permission java.security.AllPermission;
    };

    // ========== 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 DataSource's and
      // javamail named MimePart DataSource used to send mail
      permission java.utim.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 getting BeanInfo
      permission java.lang.RuntimePermission "accessClassInPackage.sun.beans.*";

      // Allow read of JAXP compliant XML parser debug
      permission java.util.PropertyPermission "jaxp.debug", "read";
    };

    // You can assign additional permissions to particular web applications by
    // adding additional "grant" entries here, based on the code base for that
    // application, /WEB-INF/classes/, or /WEB-INF/lib/ jar files.
    //
    // Different permissions can be granted to JSP pages, classes loaded from
    // the /WEB-INF/classes/ directory, all jar files in the /WEB-INF/lib/
    // directory, or even to individual jar files in the /WEB-INF/lib/ directory.
    //
    // For instance, assume that the standard "examples" application
    // included a JDBC driver that needed to establish a network connection to the
    // corresponding database and used the scrape taglib to get the weather from
    // the NOAA web server.  You might create a "grant" entries like this:
    //
    // The permissions granted to the context root directory apply to JSP pages.
    // grant codeBase "file:${catalina.home}/webapps/examples/-" {
    //   permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect";
    //   permission java.net.SocketPermission "*.noaa.gov:80", "connect";
    // };
    //
    // The permissions granted to the context WEB-INF/classes directory
    // grant codeBase "file:${catalina.home}/webapps/examples/WEB-INF/classes/-" {
    // };
    //
    // The permission granted to your JDBC driver
    // grant codeBase "file:${catalina.home}/webapps/examples/WEB-INF/lib/driver.jar!/-" {
    //   permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect";
    // };
    // The permission granted to the scrape taglib
    // grant codeBase "file:${catalina.home}/webapps/examples/WEB-INF/lib/scrape.jar!/-" {
    //   permission java.net.SocketPermission "*.noaa.gov:80", "connect";
    // };

### Starting Tomcat with a SecurityManager

Once you have configured the catalina.policy file for use with a SecurityManager, Tomcat can be started with the SecurityManager in place by using the "-security" option to bin/startup.sh.

## Trouble shooting catalina.policy configuration and Security Violations

You can turn on Java SecurityManager debug logging by settting the environmental variable `CATALINA_OPTS=-Djava.security.debug=all`. You will find the debug output in the log file `logs/catalina.out`.
This generates many MB's of output, for more verbose security debug output use `CATALINA_OPTS=-Djava.security.debug=access,failure. Use the following shell command to determine all the security debug options available: java -Djava.security.debug=help`

### What happens when the SecurityManager detects a Security violation?

The JVM will throw an AccessControlException or a SecurityException when the SecurityManager detects a security policy violation.