Gelin Luo
Gelin Luo

Reputation: 14373

Prevent a thread to execute certain methods

I have a template system allows user to input template source code and execute them. The template source code could access to any arbitrary Java object including System,Runtime and IO classes.

The question is how to prevent the executing thread from calling certain methods such as System.exit, new FileOutputStream etc.

Upvotes: 1

Views: 406

Answers (3)

Tom Hawtin - tackline
Tom Hawtin - tackline

Reputation: 147164

Assuming we are talking about an interpreter rather than generated code. With a SecurityManager installed, privileges can be reduce by having a policy that reduces permissions of the interpreter code.

If you use the two-argument forms of java.security.AccessController.doPrivileged, then there are issues with calling methods that check the immediate caller and ignore anything passed that (for example, AccessController.doPrivileged).

Obviously hosting untrusted code exposes a huge attack surface. You can hide some of your own code by using class loaders which are peers of one another in the class loader hierarchy. The security property package.access is also useful (although you still need separate class loaders).

Upvotes: 1

Jatin
Jatin

Reputation: 31724

O there are some ways to do it. But the most decent way is to use a Security Manager and write your own Class Loader (Shouldn't take much time as a google search will give you lots of example :) ). When you load a class (That was compiled and loaded at run time) to the Class Loader you need to specify the Security Manager. In that code you can provide the restrictions.

I do not know if its a legal link or not, but this should help.

This can also help.

Upvotes: 1

ShyJ
ShyJ

Reputation: 4640

One (quite heavy, but feasible) way to do it is this:

  1. Using a Java agent transform all loaded (in the past and in the future) classes so that the invocations of your blacklisted methods are actually redirected to a different method. You may use ClassFileTransformer and ASM for it. So e.g. a call to System.exit would now invoke MySystem.exit. Of course MySystem should not be transformed.
  2. The code of MySystem.exit may conditionally invoke System.exit based e.g. on a ThreadLocal variable.
    public class MySystem {
        private static final ThreadLocal callOriginal = new ThreadLocal ();

        static public final void exit (int code) {
            if (Boolean.TRUE.equals (callOriginal.get ())) {
                System.exit (code);
            }
        }
    }
  1. For the threads that you want to invoke original calls set this ThreadLocal to true, for the others to no.

You may want to have a look at time-machine library source code for similar solution.

Upvotes: 2

Related Questions