The Apache Tomcat 5.5 Servlet/JSP Container - Security Manager HOW-TO
The Apache Tomcat 5.5 Servlet/JSP Container
Links
Docs Home
FAQ
User Guide
1) Introduction
2) Setup
3) First webapp
4) Deployer
5) Manager
6) Realms and AAA
7) Security Manager
8) JNDI Resources
9) JDBC DataSources
10) Classloading
11) JSPs
12) SSL
13) SSI
14) CGI
15) Proxy Support
16) MBean Descriptor
17) Default Servlet
18) Clustering
19) Load Balancer
20) Connectors
21) Monitoring and Management
22) Logging
23) APR
24) Virtual Hosting
Reference
Release Notes
Apache Tomcat Configuration
JK 1.2 Documentation
Servlet API Javadocs
JSP API Javadocs
Apache Tomcat Development
Building
Changelog
Status
Developers
Functional Specs.
Apache Tomcat Javadocs
Apache Jasper Javadocs
Architecture
The Apache Tomcat 5.5 Servlet/JSP Container
Security Manager HOW-TO
Table of Contents
Background
Permissions
Standard Permissions
Tomcat Custom Permissions
Configuring Tomcat With A SecurityManager
Configuring Package Protection in Tomcat
Troubleshooting
Background
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 file system, connecting to a host other
than the one the applet was loaded from, and so on. 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, JSPs, JSP beans, and tag libraries.
Or even inadvertent mistakes.
Imagine if someone who is authorized to publish JSPs on your site
inadvertently included the following in their JSP:
<% System.exit(1); %>
Every time this 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.
WARNING
- A security audit
have been conducted using the Tomcat 5 codebase. Most of the critical
package have been protected and a new security package protection mechanism
has been implemented. Still, make sure that you are satisfied with your SecurityManager
configuration before allowing untrusted users to publish web applications,
JSPs, servlets, beans, or tag libraries.
However, running with a
SecurityManager is definitely better than running without one.
Permissions
Permission classes are used to define what Permissions a class loaded
by Tomcat will have. There are a number of Permission classes that are
a standard part of the JDK, and you can create your own Permission class
for use in your own web applications. Both techniques are used in
Tomcat 5.
Standard Permissions
This is just a short summary of the standard system SecurityManager
Permission classes applicable to Tomcat. See
for more information.
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()
. Also control the package access/definition.
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 utilizes 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 matching for a JNDI named file resource when
granting permission. For example, you might include the following
in your policy file:
permission org.apache.naming.JndiPermission "jndi://localhost/examples/*";
A Permission entry like this is generated dynamically for each web
application that is deployed, to allow it to read its own static resources
but disallow it from using file access to read any other files (unless
permissions for those files are explicitly granted).
Also, Tomcat always dynamically creates the following file permission:
permission java.io.FilePermission "** your application context**", "read";
Where **your application context** equals the folder(or WAR file) under which
your application has been deployed.
Configuring Tomcat With A SecurityManager
Policy File Format
The security policies implemented by the Java SecurityManager are
configured in the
$CATALINA_HOME/conf/catalina.policy
file.
This file completely replaces the
java.policy
file present
in your JDK system directories. The
catalina.policy
file
can be edited by hand, or you can use the
policytool
application that comes with Java 1.2 or later.
Entries in the
catalina.policy
file use the standard
java.policy
file format, as follows:
// Example policy file entry
grant [signedBy ] {
permission
};
The
signedBy
and
codeBase
entries are
optional when granting permissions. Comment lines begin with "//" and
end at the end of the current 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 by the
JAVA_HOME
and
CATALINA_HOME
environment variables).
The Default Policy File
The default
$CATALINA_HOME/conf/catalina.policy
file
looks like this:
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ============================================================================
// catalina.policy - Security Policy Permissions for Tomcat 5
//
// 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: catalina.policy 1087959 2011-04-02 02:03:35Z kkolinko $
// ============================================================================
// ========== 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 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-1.1.1.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 JULI
grant codeBase "file:${catalina.home}/bin/tomcat-juli.jar" {
permission java.util.PropertyPermission "java.util.logging.config.class", "read";
permission java.util.PropertyPermission "java.util.logging.config.file", "read";
permission java.io.FilePermission "${java.home}${file.separator}lib${file.separator}logging.properties", "read";
permission java.lang.RuntimePermission "shutdownHooks";
permission java.io.FilePermission "${catalina.base}${file.separator}conf${file.separator}logging.properties", "read";
permission java.util.PropertyPermission "catalina.base", "read";
permission java.util.logging.LoggingPermission "control";
permission java.io.FilePermission "${catalina.base}${file.separator}logs", "read, write";
permission java.io.FilePermission "${catalina.base}${file.separator}logs${file.separator}*", "read, write";
permission java.lang.RuntimePermission "getClassLoader";
permission java.lang.RuntimePermission "setContextClassLoader";
// Note: To enable per context logging configuration, permit read access to
// the appropriate file. Be sure that the logging configuration is
// secure before enabling such access.
// E.g. for the examples web application (uncomment and unwrap
// the following to be on a single line):
// permission java.io.FilePermission "${catalina.base}${file.separator}
// webapps${file.separator}examples${file.separator}WEB-INF
// ${file.separator}classes${file.separator}logging.properties", "read";
};
// 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;
};
// The permissions granted to the balancer WEB-INF/classes and WEB-INF/lib directory
grant codeBase "file:${catalina.home}/webapps/balancer/-" {
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.tomcat.util.digester";
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.tomcat.util.digester.*";
};
// ========== 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.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.*";
// Precompiled JSPs need access to this system property.
permission java.util.PropertyPermission "org.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER", "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 "jar: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 "jar: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 a SecurityManager in
place by using the "-security" option:
$CATALINA_HOME/bin/catalina.sh start -security (Unix)
%CATALINA_HOME%\bin\catalina start -security (Windows)
Configuring Package Protection in Tomcat
Starting with Tomcat 5, it is now possible to configure which Tomcat
internal package are protected againts package definition and access. See
for more information.
WARNING
: Be aware that removing the default package protection
could possibly open a security hole
The Default Properties File
The default
$CATALINA_HOME/conf/catalina.properties
file
looks like this:
# List of comma-separated packages that start with or equal this string
# will cause a security exception to be thrown when
# passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted.
package.access=sun.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,
org.apache.jasper.
# List of comma-separated packages that start with or equal this string
# will cause a security exception to be thrown when
# passed to checkPackageDefinition unless the
# corresponding RuntimePermission ("defineClassInPackage."+package) has
# been granted.
# by default, no packages are restricted for definition, and none of
# the class loaders supplied with the JDK call checkPackageDefinition.
package.definition=sun.,java.,org.apache.catalina.,org.apache.coyote.,
org.apache.tomcat.,org.apache.jasper.
Once you have configured the
catalina.properties
file for use
with a SecurityManager, remember to re-start Tomcat.
Troubleshooting
If your web application attempts to execute an operation that is
prohibited by lack of a required Permission, it will throw an
AccessControLException
or a
SecurityException
when the SecurityManager detects the violation. Debugging the permission
that is missing can be challenging, and one option is to turn on debug
output of all security decisions that are made during execution. This
is done by setting a system property before starting Tomcat. The easiest
way to do this is via the
CATALINA_OPTS
environment variable.
Execute this command:
export CATALINA_OPTS=-Djava.security.debug=all (Unix)
set CATALINA_OPTS=-Djava.security.debug=all (Windows)
before starting Tomcat.
WARNING
- This will generate
many megabytes
of output! However, it can help you track down problems by searching
for the word "FAILED" and determining which permission was being checked
for. See the Java security documentation for more options that you can
specify here as well.
Copyright © 1999-2012, Apache Software Foundation