From: Roland.Schemers@Eng (Roland Schemers)
Message-Id: <199710280355.TAA11867@crypto.eng.sun.com>
Subject: Re: java.securty.AccessControlContext
To: clark.evans@gartner.com (Clark Evans)
Date: Mon, 27 Oct 1997 19:55:15 -0800 (PST)
In-Reply-To: <199710280234.AA24864@interlock.gartner.com> from "Clark Evans" at Oct 27, 97 09:36:04 pm
>
> Before we continue with the openFileForSearching call, is
> there a determinstic way to know that the Searcher is untrusted?
> Do the class loaders have to be different? Or do the package
> names have to be different, does like: xxx.core.Explorer and xxx.addin.Searcher?
There is really no way to tell. As in the security spec, classes belong
to a protection domain, and that is what determines which permissions
a class has. Not its class loaders or the package name.
> // Stack: searcher.run(), obExplorer.openFileForSearching()
> //
...
> Thus the Explorer object (obExplorer) currently exists in a
> trusted domain that allows full file access. The searcher
> is in an untrusted domain that limits access.
>
> Revised questions:
>
> A) Why is the begin/end Privleged needed? I do not see
> the security breach.
Without a begin/endPrivileged the open would always fail. The
algorithm (described in AccessController) says:
*
* for each domain on the stack {
* if (domain does not have permission)
* throw AccessControlException
* else if (domain is marked as privileged)
* return;
* }
*
* // if all of them allow access, then check the context inherited when
* // the thread was created. Whenever a new thread is created, the
* // AccessControlContext at that time is
* // stored and associated with the new thread, as the "inherited"
* // context.
*
* for each domain inherited from the thread that
* created the current thread {
* if (domain does not have permission)
* throw AccessControlException
* else if (domain is marked as privileged)
* return;
* }
(note, this might be slightly different then docs you are reading).
The jist is in the first for loop:
*
* for each domain on the stack {
* if (domain does not have permission)
* throw AccessControlException
* else if (domain is marked as privileged)
* return;
* }
Even if the explorer object has permission to read the file, it
was called by code that did not have permissions, so an AccessControlException
would be thrown.
i.e., with no begin/endPrivileged:
1. You check: openFileForSearching
It has permissions. It is not privileged, so you check its caller
2. You check: searcher.run
It doesn't have permissions. You throw an AccessControlException
with begin/end:
1. You check: openFileForSearching
It has permissions. It is privileged, so you return
One of the strengths of this algorithm is to prevent the case when
untrusted code calls trusted code. You don't want the trusted code doing
something it shouldn't. Therefore, the trusted code must have a begin/endPriv
to state that it knows what it is doing.
The other strength is you don't want trusted system code calling into
untrusted code (such as an event handler), and then letting the untrusted
code take advantage of the trusted code's permissions.
> B) Why cannot the Explorer object simply "give" a permission
> to the searcher that allows the files needed to be read for
> a limited time? (By extending it's AccessControlContext..)
Thats simply not how it works, so that won't work :-)
Seriously, we wanted to keep things as simple as possible, and
therefore everything follows the above algorithm. There are plenty
of ways this stuff could have been designed, but we decided to keep it
simple.
We might be modifying SecureClassLoader so it has a way to extend permissions
for classes while they are getting loaded (to support the "applet" sandbox
for example), and this might be useful in the case you describe, but
in general it sounds like what you are tring to do might be dangerous.
Just giving permissions (even if it is just "read") to any old searcher
object (that you might never have seen before) could be very dangerous.
The policy/protection-domain model is supposed to be a little more static,
and a little more pre-configured then what you are trying to do. Not
to say that dynamic granting of permissions is a bad thing, just that it
might be possible to do what you want in the current model, you just
have to be careful.
roland