How do I secure scripts run using javax.scripting?
javascript, javax.script, security, server-side-scripting
Solution
It turns out that `javax.scripting` does not offer a security framework. After some searching I found a document in Google's cache that suggested trying to use Java's `doPrivilegedAction` framework but after some experimentation, I was unable to get this to prevent the scripts from opening sockets or accessing the filesystem.
After I asked this question I discovered it was previously asked here on StackOverflow: How can you run Javascript using Rhino for Java in a sandbox? On that page, it falsely indicates that the Rhino included in the JDK6 has security worked out already. As I indicated, I was able to open sockets and other harmful actions from the script.
In the end I abandoned `javax.scripting` and embedded Rhino directly. By building a custom `ContextFactory` that is also a `ClassShutter` I was able to achieve two results easily:
- Restricts script execution time to a maximum time limit
- Restricts class access to those I have white-listed, which is basically `java.lang.*` and a select few classes in my server's hierarchy.
CodeUtopia (which I can't link to because, as a new user, I'm not allowed to link to multiple pages in a single post; but it's linked in the other StackOverflow post) was valuable in describing the `ClassShutter` architecture and Rhino's own `ContextFactory` API page describes how to build a custom `ContextFactory`.
Problem
I am using `javax.scripting` to add support for running arbitrary user-uploaded JavaScripts on the server-side. Obviously I want to secure those scripts! Rhino, on it's own, has a framework for securing scripts at runtime. The documentation for `javax.scripting`, however, doesn't mention security, permissions or restricting classes available to the script. So is this just a huge hole in the `javax.scripting` API that it doesn't offer a framework to secure scripts it executes? I don't want to use Rhino directly because I originally tried that but had some problems exposing Java instances to the running script. The `javax.scripting` framework made it (which uses Rhino under the hood) made this trivial and also simplified running scripts in a multi-threaded server. I would like to white-list Java classes that can be accessed/instantiated within the running script. Can anyone point me to an example or documentation on how to achieve this?