cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Robert Stupp (JIRA)" <>
Subject [jira] [Commented] (CASSANDRA-9402) Implement proper sandboxing for UDFs
Date Mon, 15 Jun 2015 12:23:01 GMT


Robert Stupp commented on CASSANDRA-9402:

Pushed an update of sandboxing to my branch and wanted to provide some status of the work.

* Uses a global, custom implementation of a {{SecurityManager}} and {{Policy}}. The security-manager
only performs permission checks for user-defined functions (try-finally with a {{ThreadLocal}})
- this eliminates the previously mentioned 3% pref regression. ([cstar|]).
* The effective {{Permissions}} set for UDFs is empty (Java and Javascript). No access to
files, sockets, processes, etc.
* UDFs only have access to a very restricted set of classes.
** This works very nicely for Java UDFs. Direct use and {{Class.forName()}} approaches are
prevented. Access to {{Runtime}}, {{Thread}} and other ”evil” classes is prevented with
a compiler error or {{ClassNotFoundException}}.
** Scripted UDFs need to take the {{SecurityManager.checkPackageAccess()}} approach (see below),
which results in an {{AccessControlException}}.
** So Nashorn unfortunately still allows code like {{java.lang.Runtime.getRuntime().gc()}}
- but Nashorn does a nice job to prevent bad access in general.
** Thread starting required some special casing in the sec-mgr (the default permission handling
in {{java.lang.SecurityManager}} is … well … could be improved). Java {{SecurityManager}}
is kind of dangerous because it explicitly allows thread creation and modification of all
threads that do not belong to the root thread group (source code cite: {{// just return}}).

* I did not test this with other JSR223 implementations. Security heavily depends on the implementation
of the scripting engine. All UDFs are executed within a {{doPriviledged()}} and the UDF class
loader as the thread’s context class loader.
* Did also not test against Rhino (Java7) due to the tentative "decision" for Java8 for 3.0

White/blacklisting of classes (class loading):
I tried to find something that’s better than WB, but honestly could not find anything better.
It works as follows:
# only whitelisted pattern ({{startsWith}}) are allowed - if not found, then it’s not accessible
# if the individual pattern matching a whitelist entry is contained in the blacklist, then
it’s not accessible
# so, patterns matching whitelist and not matching blacklist are allowed

It is possible to consume a lot of CPU with an endless loop or to force a lot of GCs using
Nashorn ({{java.lang.Runtime.getRuntime().gc()}}).
Will work on finding a solution for that (separate pooled threads, adopted thread priority,
maximum execution time + UDF blacklisting) - maybe with a separate class loader hierarchy.

I’m not completely sold on moving UDF execution to a separate process (fenced UDFs).
TBH I think it adds too much complexity - requires a new IPC/RPC protocol, state management,
recovery scenarios, etc. plus child process (state) management + recovery.
To make it really safe, each individual invocation would have to spawn its own process, that
has to be monitored.

We can probably not prevent UDFs from excessive use of heap space (by accident or bad intention).

Other implementations:
* JEE containers rely on a (more or less) standard {{SecurityManager}} + {{Policy}} implementation
for the whole VM. These usually rely on proper class loader separation.
* Some other projects use user-provided code - either these projects have no or effectively
no security/sandboxing.

> Implement proper sandboxing for UDFs
> ------------------------------------
>                 Key: CASSANDRA-9402
>                 URL:
>             Project: Cassandra
>          Issue Type: Task
>            Reporter: T Jake Luciani
>            Assignee: Robert Stupp
>            Priority: Critical
>              Labels: docs-impacting, security
>             Fix For: 3.0 beta 1
>         Attachments: 9402-warning.txt
> We want to avoid a security exploit for our users.  We need to make sure we ship 2.2
UDFs with good defaults so someone exposing it to the internet accidentally doesn't open themselves
up to having arbitrary code run.

This message was sent by Atlassian JIRA

View raw message