1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<meta NAME="Author" CONTENT="Martin Pool">
<title>Servlet Sandboxing</title>
</head>
<body BGCOLOR="#FFFFFF">
<p align="center"><a href="http://java.apache.org/" target="_top"><img SRC="../images/java-apache-project.gif" BORDER="0" WIDTH="609"
HEIGHT="100" ALT="The Java Apache Project"></a></p>
<h1 align="center">Servlet Sandboxing</h1>
<h2>Introduction</h2>
<blockquote>
<p>This is an discussion for developers and interested bystanders of implementing zones
and security in Apache JServ. It describes the point of the feature, different
implementation alternatives, and current problems. Please send comments to the mailing
lists. </p>
</blockquote>
<h2>Intention</h2>
<blockquote>
<p>Each `servlet mount point' in the web server specifies the name of a <em>servlet zone</em>
for that virtual directory. Servlet zones partition up the Apache JServ virtual machine
into secured, separated spaces for different applications or users. It will be impossible
for code inside one zone to see or interact with code in another zone; and for code inside
a zone to interact with the Java server implementation except through defined interfaces.
Zones can be thought of as solipsistic little JServ engines, but without the overhead of
running a separate JVM for each zone. This will allow multiple users to work on a single
web server without needing to run multiple VMs; and for people to use untrusted servlet
code safely. This proposal assumes a socket-based connection vaguely similar to that of
AJPv1.1 and our current consensus on AJPv2.1. Interested people are referred to the Java
Language Specification for more details and legalese. </p>
</blockquote>
<h2>Interface</h2>
<blockquote>
<p>The web server module will pass the name of the zone in each request. </p>
<p>The Apache JServ configuration files contain default properties and per-zone
properties. </p>
<p>Per-zone properties include: A security ACL, specifying operations that are allowed and
disallowed A list of repositories (directories, ZIPs, and JARs) to be searched for
classes. Whether autoreloading of changed classes should happen or not. Servlet aliases,
mapping short names (jobservlet) into fully-qualified class names
(org.apache.java.JobServlet). A list of servlets to be loaded at start-up, and
initialization arguments. Pool management settings. [others?] </p>
<p>Global properties include The authentication string. Tracing options [others?] </p>
<p>Classes may be loaded into a Java virtual machine either using the default classloader
provided by the VM, or using a custom classloader implementation. When ClassLoaders are in
play, there may be several classes in the JVM with the same canonical name. The JVM looks
up classes using a dictionary keyed by class name and classloader. </p>
<p>A JVM initially has no SecurityManager installed. Once a SecurityManager has been
installed, it is illegal to try to install (or even construct) a new one. </p>
<p>JServ will install a JServSecurityManager object at startup: this object allows full
privileges to JServ code and restricts user code depending on the zone from which it is
loaded. </p>
<p>Operations subject to SecurityManager control include: System.exit() Linking native
libraries Executing external programs Reading/writing/deleting files/directories
Listening/connecting to TCP ports Creating/stopping/suspending threads </p>
<p>Servlet zones are represented by a JServZone object. This class will be similar to
JServServletManager in 0.9. When JServ receives a request from the server, it will look up
the name and route it to the appropriate zone for handling. </p>
<p>Each zone uses a single JServClassLoader at any time. This classloader loads classes
from the repositories specified for that zone. The classloader has the option of requiring
that certain classes be loaded from the system, rather than from user directories. The
JServClassLoader will refuse to load classes in java.*, javax.*, or org.apache.jserv.*
from within the zone repositories. (Allowing users to install classes into these packages
might give them access to security-critical default-access members.) </p>
<p>JServ 0.9.7 already uses ClassLoaders in a similar fashion to reload changed classes. </p>
<p>System classes are taken from the classpath specified when the JVM is started.
Generally, this path should only include java.*, javax.*, and org.apache.*, but other
classes that definitely will not change and which can be shared across all zones (perhaps
for example database drivers) may be included. </p>
<p>The Java VM will not permit a ClassLoader to redefine a class once it has supplied a
definition. However, it will permit us to request that a class of the same name be loaded
from a different classloader, as from Java's point of view this is a different Class.
Therefore, when a JServZone detects that a repository element has been changed, it
discards the classloader, creates a new one, and reloads the class. </p>
<p>If an operation is disallowed, generally it throws a SecurityException (extends
RuntimeException) which if uncaught will terminate the servlet. If an operation is
allowed, it completes normally. </p>
<p>Optionally, we should log all attempted security violations, even if they are caught by
client code. </p>
<p>When the SecurityManager is called, it has to determine which zone the call comes from.
</p>
</blockquote>
<h2>Implementation by ThreadGroups</h2>
<blockquote>
<p>One possible implementation is to run each zone within a separate ThreadGroup, and have
the SecurityManager check which ThreadGroup called it. </p>
<p>All operations within a particular zone take place within a particular ThreadGroup.
Classes in that zone can create new Threads, and new ThreadGroups as children of their
group, but may not create threads within other ThreadGroups, or stop or signal threads in
other zones. </p>
<p>This could be implemented by creating a new thread within the appropriate ThreadGroup
on each request, similar to the way new threads are created to handle each request in
0.9.7. Better, since WorkerPool extends ThreadGroup it should be possible to use Worker
Pools and gain their performance advantage. </p>
<p>When the JServSecurityManager is asked to check an operation, it identifies the
ThreadGroup from which the operation was called, and finds the JServZone which owns that
ThreadGroup. If the ThreadGroup was not directly created by a Zone, then the
JServSecurityManager checks its parents recursively to see if any of them execute within a
zone. </p>
<p>If none of the ThreadGroups belong to a zone, then the operation is being attempted
from system code or JServ itself and generally should be allowed. </p>
</blockquote>
<h2>Implementation by JDK1.2 Security</h2>
<blockquote>
<p>JDK1.2b4 includes a very flexible standard means of specifying policy based on code
location and signatures. It makes an Apache JServ specific implementation fairly
redundant. </p>
<p>Some changes may be necessary in the ClassLoader implementation in JDK1.2 to do secure
ClassLoaders. </p>
</blockquote>
<h2>Sessions</h2>
<blockquote>
<p>Sessions are private to each zone: the session cookie ID will include the zone name, so
that more than one zone can have sessions open on a particular browser at the same time.
Other zones will be able to see the cookie IDs, of course, by examining the headers, but
they will not have access to the server-side objects it points to. </p>
<p>There's a possible attack in which a hostile servlet connects back to the web server's
http port and pretends to be a client presenting the cookie it just sniffed. An
administrator should take advantage of the security manager's ability to limit outgoing
sockets to turn this off it they expect malicious and sophisticated code. </p>
</blockquote>
<h2>Issues</h2>
<blockquote>
<h3>Conflicting SecurityManagers</h3>
<blockquote>
<p>A JVM may only have a single SecurityManager loaded at any time, and once installed it
may not be replaced. </p>
<p>Some other applications require SecurityManagers to be loaded, and they _may_ not be
able to execute within a JServ VM. (RMI, for example, should be compatible as it only
requires a security manager but does not care what class it is.) I would be interested to
hear from people who think this might be a problem. </p>
</blockquote>
<h3>Backward compatibility</h3>
<blockquote>
<p>The default settings for security are a bit of a conundrum: for compatibility with
0.9.7, we ought to ship with everything allowed so as not to break existing code; but
shipping with all the doors unlocked earns one a bad reputation. </p>
</blockquote>
</blockquote>
<p align="center"><font SIZE="-1">Copyright (c) 1997-98 <a HREF="http://java.apache.org/" target="_top">The
Java Apache Project</a>.<br>
$Id: sandboxing.html,v 1.3 1999/06/09 05:21:26 jonbolt Exp $<br>
All rights reserved.</font> </p>
</body>
</html>
|