Right, good analysis! I have further important additions to #1 and #2:

#1 of course is difficult. It should be split up:
-----------------------------------------------------

1a. malicious JSP/script code

Injecting a script that gets executed by Sling can be a lot easier (incorrect 
ACLs on production systems) than deploying a bundle (which should only possible 
with admin). This is definitely a goal that Sling should have: that you can 
make sure scripts can be fully sandboxed.

There are 2 important separations: access to java APIs and - since it is core 
to Sling - access to the resources / jcr. The first should be possible by just 
whitelisting APIs a script can use (e.g. no System.exit()) while the latter 
requires a fully safe authentication mechanism that is handled on the jcr side.

1b. malicious bundles reading from JCR through the API

Even if a bundle could be installed, IMO it is not clear that it should have 
access to the data in the resource tree (JCR). A service user mapping config 
_could_ in theory be implemented safely so that you cannot circumvent it 
through Java code (that's what I was refering to in my original mail). This 
would make the JCR safe (ignoring the issue of reading the repo via the file 
system or reloading the repo bundle).

1c. malicious bundles in general

Of course, if an attacker can install bundles, he could do:
- malicious code: things like System.exit(), endless loops
- access critical infra services (OSGi admins, crypto service etc.)
- try to read osgi config data from the filesystem
- try to read the repository data directly through the filesystem (i.e. using a 
customized jackrabbit bundle without authentication)

Ignoring how much work it would be in the end, solutions that IMO are at least 
possible:
- a new "OSGi sandboxing", so that they cannot import all packages/classes, but 
just a subset (e.g. no "System.*"; a simpler way than JaaS); to avoid 
permission management hell for normal product development, you'd only do this 
in production with a "seal now" button, so that permissions are restricted only 
for newly added (malicious) bundles
- similarly, disable file system permissions through JaaS, as a whitelist on a 
production system (configured in the filesystem and not through a web UI 
provided by Sling itself, or at least not with a replaceable bundle, so you 
couldn't hack the configuration)
- remember, the JCR access was protected already through safe authentication; 
no need for making the jcr packages invisible or inventing a JaaS permission, 
as JCR already has an auth mechanism


With 1b and 1c in place, even a malicious bundle could not steal arbitrary data 
from the repository (unless exposed by other services through an API, 
internally using a loginByService() with a more powerful user; which in most 
cases is wrong; note that all other code would be implicitly using the request 
session).

If you say "it's impossible" it will be a self-fulfilling prophecy: you add new 
stuff that doesn't care about the clear boundaries, and then it is indeed 
impossible to find a way to shield things from each other. Before you can think 
about using JaaS, you have to have clear APIs and boundaries, so that 
permissions are simple and obvious and not too complex.


Also, there is an important case for #2:
-----------------------------------------------------

2. 3rd party "app bundles"

Running 3rd party apps on a multi-tenant Sling instance, managed by one 
organization, but apps provided by others. Here the requirement to make sure 
code cannot circumvent users listed in the sling user mapper might be more 
important. A safe mechanism would be useful here to reduce the things the 
bundle has to be tested and reviewed for.

Also, here you maybe want deliberate sandboxing with just a few APIs accessible 
(similar to 1a with scripts).


Conclusion:
------------------

We should definitely aim for #1a, #2 and #3.

#1b and c should be designed for, even if we can't implement that mechanism 
right away.


BTW, Something that comes to my mind whenever I mention "sandboxing" above is 
the "Object capability model" [1], where code can only do what interfaces it 
gets access to. This is hard in a Java context which can load any class on the 
classpath by default, giving it access to everything. Instead of the JaaS 
approach, which simply acknowledges this fact, and thus has to add a permission 
concept to deny access, you could also think about simply disabling the 
importing in the first class, which should be feasible with a pure OSGi system.

[1] http://en.wikipedia.org/wiki/Object-capability_model

Cheers,
Alex

Reply via email to