Re: Run-time configurable sandboxes

2015-05-26 Thread Bernd Eckenfels
Hello,

partial quote as I want to add to a point:

Am Tue, 26 May 2015 16:19:59 -0400
schrieb Michael Maass mma...@andrew.cmu.edu:

 3. Common security reasons to use the sandbox: (a) using a third
 party library that isn't fully trusted (convenience often trumps
 security) and (b) frameworks loading third party plugins.

From looking at CVEs it looks like the only other common reason not
mentioned here is multi tenancy for Web Application Servers (i.e.
seperate WAR deployments). 

And I am quite sure by now (i.e. contains and other PaaS technolgies) 
nobody considers that anymore. So the biggest user might as well be
Google App Engine (not sure how far their special platform relies on
the security manager).

Gruss
Bernd

PS: Michael I would be interested in your paper for my personal
education.


Re: Run-time configurable sandboxes

2015-05-26 Thread Michael Maass
I've been working on addressing similar issues as part of my PhD thesis 
and have noted many of the same challenges, although I've taken a 
different approach. Some points I can add from a recent but currently 
unpublished study of actual usage of the Java sandbox (I can send a 
draft to individuals on request):


1. Almost no one uses the Java sandbox, and out of those that do, quite 
a few are using it for reasons that have nothing to do with security. We 
factored out applets because applets are dead (see builtwith stats on 
applets) and did not directly use the sandbox themselves. While we did 
look at web start applications, in practice, vendors seem to always sign 
them and request all permissions. I personally believe the latter is 
common because it's currently too hard to figure out what permissions a 
non-trivial set of Java code needs.


2. Almost everyone using the Java sandbox that cares about security is 
using it incorrectly, often in ways that ensure using the sandbox is 
entirely ineffective. The most common issue is completely 
misunderstanding the permission model (i.e. believing it's a blacklist 
instead of a whitelist). This often leads people to accidentally use one 
of several Java permissions that are so powerful you might as well not 
use the sandbox if you grant them.


3. Common security reasons to use the sandbox: (a) using a third party 
library that isn't fully trusted (convenience often trumps security) and 
(b) frameworks loading third party plugins.


My solution has been to create tooling to let software deal with the 
complexity while letting the user deal with higher level concerns. I 
have a full prototype tool suite that let's users pick a specific set of 
classes and JAR's in an application to sandbox. The tools then use 
static and dynamic analysis to develop a starter policy for the selected 
subset that contains all of the permissions required by every execution 
of the subset. Finally, the tools let the user review the policy and 
edit it in a little IDE that warns them if they do something dangerous 
to establish the final policy. The tools then impose the final policy on 
the application by re-writing the bytecode. The basic approach the 
bytecode re-writing implements is very similar to what you described and 
for the same reasons.


I went with a tooling approach in acknowledgment of the fact that the 
Java sandbox is hard to use because it's quite flexible in many ways. 
Instead of losing that flexibility, I feel it is better to separate 
complexity a human must deal with from that a machine can deal with and 
let each deal with their own concerns. Tooling also has the advantage 
that it can be adopted without the potentially lengthy process required 
to change the sandbox in the JVM itself. What I've learned is that the 
Java sandbox is, for most practical intents and purposes, impossible to 
use manually without causing problems, but that it's extremely handy 
when tools do most of the heavy lifting for you.


Michael

On 05/25/2015 11:41 AM, org.open...@io7m.com wrote:

Hello!

I am a security-conscious Java developer and am interested in using the
JVMs built-in security features to run code in separated and run-time
configured sandboxes. I'm writing to the list to explain some of the
issues I've come up against and am hoping to either elicit suggestions
or at least provoke some discussion about how the JVM might better
support this.

I've been working on a small experimental system for sandboxing
due to dissatisfaction with the existing sandboxing packages.
The existing sandboxing packages appear to be overly complicated,
fragile, and unmaintained. They almost all implement a complicated
and error-prone custom security manager and seem to more or less
ignore everything else the JVM has in terms of security features.
I'm hoping that I can do better!

My own use case will be running code that is sandbox-aware and that
only uses a few classes from java.lang and talks to an API that I
provide to each sandbox. I would expect to restrict arbitrary file
I/O (with sandboxed code persisting state via provided key/value
interface), restrict network I/O, restrict access to native code,
restrict access to reflection, restrict thread creation, and restrict
exiting the VM. About the only thing I cannot protect against is
heap exhaustion (but the JVM does a decent job of enforcing a global
limit anyway, so it's not as if malicious code would end up killing
the user's machine or running afoul of operating system limits).

It seems that others have somewhat similar use cases, often using
some sort of sandbox to provide security to embedded languages that
have been compiled to JVM bytecode at run-time.

I won't bore anyone here with the details of how the JVM applies
security policy because I'd assume everyone on this list already
understands it.

My basic approach has been to use a custom implementation of
java.security.Policy[0] and a custom classloader. The program

Run-time configurable sandboxes

2015-05-25 Thread org . openjdk
Hello!

I am a security-conscious Java developer and am interested in using the
JVMs built-in security features to run code in separated and run-time
configured sandboxes. I'm writing to the list to explain some of the
issues I've come up against and am hoping to either elicit suggestions
or at least provoke some discussion about how the JVM might better
support this.

I've been working on a small experimental system for sandboxing
due to dissatisfaction with the existing sandboxing packages.
The existing sandboxing packages appear to be overly complicated,
fragile, and unmaintained. They almost all implement a complicated
and error-prone custom security manager and seem to more or less
ignore everything else the JVM has in terms of security features.
I'm hoping that I can do better!

My own use case will be running code that is sandbox-aware and that
only uses a few classes from java.lang and talks to an API that I
provide to each sandbox. I would expect to restrict arbitrary file
I/O (with sandboxed code persisting state via provided key/value
interface), restrict network I/O, restrict access to native code,
restrict access to reflection, restrict thread creation, and restrict
exiting the VM. About the only thing I cannot protect against is
heap exhaustion (but the JVM does a decent job of enforcing a global
limit anyway, so it's not as if malicious code would end up killing
the user's machine or running afoul of operating system limits).

It seems that others have somewhat similar use cases, often using
some sort of sandbox to provide security to embedded languages that
have been compiled to JVM bytecode at run-time.

I won't bore anyone here with the details of how the JVM applies
security policy because I'd assume everyone on this list already
understands it.

My basic approach has been to use a custom implementation of
java.security.Policy[0] and a custom classloader. The program
creates one classloader C per application sandbox S and assigns
all classes loaded by C a protection domain P. My assumption is
that for a particular sandbox, we no longer care about fine-grained
per-CodeSource control of classes inside the sandbox as we're more
likely to be applying a coarse sandbox-wide set of restrictions. This
then means that that the custom Policy implementation can assign
permissions on a per-sandbox basis by simply checking the CodeSource
URL and returning any permissions defined for that URL.

As a concrete example, I create a sandbox that I then assign
a URL of http://sandbox.io7m.com/1. The classloader for that
sandbox assigns every loaded class a CodeSource with location
http://sandbox.io7m.com/1. Now, whenever the AccessController consults
the policy's checkPermission function, the policy simply uses the
set of permissions defined for http://sandbox.io7m.com/1.

As an aside, I do use a custom SecurityManager but only to add a couple
of extra checks for Thread and ThreadGroup creation/modification,
because the default SecurityManager is not strict enough.

This appears to work well. I've been unable to subvert the sandbox and
am reasonably confident in its security simply due to the fact that it
does absolutely nothing clever whatsoever and uses the basic provided
JVM security features to achieve it. The code is less than 150 lines
and is not exciting in any way. The bulk of a real implementation
would be providing a pleasant API and a nice way to configure policies
at run-time.

My main gripes:

1. The ClassLoader and SecureClassLoader classes are not very nice. It
seems that I cannot take an existing classloader and preserve all
of the semantics with regards to mapping names to byte arrays (such
as looking through the classpath for class files, contacting remote
servers for classes, etc) if I want to maintain my own control over
the resulting ProtectionDomains of those classes. It is likely that
ProtectionDomains and CodeSources were never intended to be used in
the slightly abusive way I'm using them in the above system. I'm
guessing also that the implementations carry a ton of historical
baggage and would likely not have their interfaces presented in the
way they currently are if they were written/designed today!

There is a tempting package-private method in java.lang.Class called
setProtectionDomain that I'm not allowed to call. Having access to this
would allow me use any existing class loader and simply overwrite the
protection domains of the resulting classes without having to modify
any code.

2. I feel like I should not have to do any of the things I have done!
I realize this sounds silly, but if it were possible to label classes
with a simple immutable opaque tag indicating their confinement, and
the Policy could refer to this tag... I'd already be done. I would
assume that setting a confinement label on a class would require
security checks and that it could only be set once. This seems
almost too good/simple an approach to be true - would it require
an unlimited amount of