Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

restricted privileges for untrusted code called from trusted code

4 views
Skip to first unread message

Tomas Mikula

unread,
Nov 20, 2009, 11:55:43 PM11/20/09
to
I can't figure out how to temporarily restrict code privileges. My code
goes like this:

// trusted code
// untrusted code
// trusted code

I would like to run untrusted code with restricted privileges and then
continue with full privileges again.

Thanks in advance!

My idea was to set a custom SecurityManager with System.setSecurityManager(s),
but then I would not be able to restore the original one. My other idea was
to use AccessController.doPrivileged(action, context), but I'm not able to
get an instance of AccessControlContext with custom permissions, and
AccessControlContext is final, so I can't implement my own.

Steven Simpson

unread,
Nov 21, 2009, 4:52:24 AM11/21/09
to
Hi!

Tomas Mikula wrote:
> I can't figure out how to temporarily restrict code privileges. My code
> goes like this:
>
> // trusted code
> // untrusted code
> // trusted code
>

In what way is the middle code untrusted? Are you invoking code unknown
at compile time, e.g. some sort of plug-in dynamically loaded from an
arbitrary location?

> I would like to run untrusted code with restricted privileges and then
> continue with full privileges again.
>

A basic way is to run java with a static security policy, and grant
AllPermission only to your own code:

# java.policy
grant codeBase "file:/place/where/my/code/is/stored/-" {
permission java.security.AllPermission;
};

java -Djava.security.manager -Djava.security.policy=java.policy ...

When the untrusted code runs, the thread's call stack is tainted by
unprivileged frames, which will prevent it from doing any system calls
(basically, anything that calls AccessController.checkPermission). When
control returns to your code, those unprivileged frames have been
discarded, so you're back to AllPermission again.

--
ss at comp dot lancs dot ac dot uk

Marcin Rzeźnicki

unread,
Nov 21, 2009, 7:04:41 AM11/21/09
to

Hi
Untrusted code is run with restricted privileges (those you
configured) by default. There is nothing you need to do to untrusted
code, its effective permission set is the intersection of all
permission sets of its callers including its own. To regain permission
when untrusted code is calling trusted code you should use privileged
action - with (a) no additional context if trusted code has full-
trust, or with (b) some context if you want to restrict permission of
privileged code. So it may well be that you need no further work if
(a) holds. If it does not you should, in my opinion, encapsulate the
"calling of untrusted/trusted code" concept into separate class (or
two coupled classes) which captures relevant security context from
AccessController.getContext() when calling untrusted code from trusted
code and then restores it (using doPrivileged) when being called in
the untrusted->trusted direction. So it should really be an interface
for untrusted code to call trusted code. If untrusted call may only
call few trusted methods than you might not expose this interface to
untrusted code explicitly but rather make these few trusted methods
use it under the hood.

Tomas Mikula

unread,
Nov 21, 2009, 11:03:56 AM11/21/09
to
On Sat, 21 Nov 2009 09:52:24 +0000, Steven Simpson wrote:

> Hi!
>
> Tomas Mikula wrote:
>> I can't figure out how to temporarily restrict code privileges. My code
>> goes like this:
>>
>> // trusted code
>> // untrusted code
>> // trusted code
>>
>>
> In what way is the middle code untrusted? Are you invoking code unknown
> at compile time, e.g. some sort of plug-in dynamically loaded from an
> arbitrary location?

The untrusted code is an interpreter of user's script. So the Java code is
known at compile time, but the script it interprets is not. The script is
intended for custom preprocessing of data. Currently, it may be XSLT
(this should be safe without any additional restrictions) or JavaScript,
but others may be added in the future. I have an interface

interface Preprocessor {
void preprocess(Reader, Writer);
}

and the implementing classes will be JavaScriptPreprocessor,
XSLTPreprocessor, ... They will be part of my application (same JAR/WAR).
I could have some SecurePreprocessor to wrap any other preprocessor and
restrict permissions for this SecurePreprocessor (but I don't know how to
do it).

>> I would like to run untrusted code with restricted privileges and then
>> continue with full privileges again.
>>
>>
> A basic way is to run java with a static security policy, and grant
> AllPermission only to your own code:
>
> # java.policy
> grant codeBase "file:/place/where/my/code/is/stored/-" {
> permission java.security.AllPermission;
> };
>
> java -Djava.security.manager -Djava.security.policy=java.policy ...

I see 2 problems for me:
1. The untrusted code (interpreter) is in the same JAR as the trusted
code. I would need per-class permissions (e.g. to restrict permissions of
the SecurePreprocessor).
2. The application will run in Tomcat. I don't have control over how
Tomcat is launched.

Tomas Mikula

unread,
Nov 21, 2009, 11:07:41 AM11/21/09
to
On Sat, 21 Nov 2009 04:04:41 -0800, Marcin Rzeźnicki wrote:

> Hi
> Untrusted code is run with restricted privileges (those you configured)
> by default.

That is my problem - how to configure the privileges. See my reply to
Steven Simpson's reply.

Tomas

Marcin Rzeźnicki

unread,
Nov 21, 2009, 11:29:22 AM11/21/09
to

If that's the problem you can implement your own Policy (http://
java.sun.com/javase/6/docs/technotes/guides/security/spec/security-
spec.doc3.html#27428)

Tomas Mikula

unread,
Nov 21, 2009, 1:56:18 PM11/21/09
to

The problem is that it doesn't allow me to specify permissions for a
certain class in a JAR file, only for the JAR file as a whole.

Marcin Rzeźnicki

unread,
Nov 22, 2009, 12:39:13 PM11/22/09
to

I am not sure, I will have to take a look at my code, but did you try
something like: jar:file:/a/path/to/jar!/path/to/class?
If that does not work, what about changing your assumptions and
placing classes in different jars?

Andrew Thompson

unread,
Nov 22, 2009, 5:28:57 PM11/22/09
to
On Nov 21, 3:55 pm, Tomas Mikula <tomas.mik...@gmail.com> wrote:
> ..My idea was to set a custom SecurityManager with System.setSecurityManager(s),

> but then I would not be able to restore the original one.

Make 's' a bit less restrictive. See
<http://forums.sun.com/thread.jspa?messageID=10773268#10773268>
for simple (naive, easy to break) example.

I think this has been said or implied by others,
but it will be vital to ensure the plug-in code
is in a different package to your own code.

--
Andrew T.
pscode.org

Teraposa Lunodas

unread,
Nov 24, 2009, 7:32:47 AM11/24/09
to
A basic way is to run java with a static security policy, and grant
AllPermission only to your own code:

# java.policy
grant codeBase "file:/place/where/my/code/is/stored/-" {
permission java.security.AllPermission;

};

java -Djava.security.manager -Djava.security.policy=java.policy ...

When the untrusted code runs, the thread's call stack is tainted by

0 new messages