1

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.

Gelin Luo
  • 14,035
  • 27
  • 86
  • 139
  • 1
    Have you considered using a [SecurityManager](http://docs.oracle.com/javase/tutorial/essential/environment/security.html)? – assylias Nov 21 '12 at 23:05
  • I don't think that a `SecurityManager` can stop the app from using `System.exit()`. The purpose is not to protect the app against itself but the system against the app. @green a Java interpreter with a limited set of functionality or some kind of sourcecode preprocessor that replaces bad methods with something ok – zapl Nov 21 '12 at 23:13
  • you might need an Aspect Oriented Programming framework. I don't know much about them, but I think they let you add custom security policies to any objects. – didierc Nov 21 '12 at 23:30
  • I don't think blacklist aproach can be secure in this situation. You need whitelist and time and memory limits. – zch Nov 21 '12 at 23:37
  • @zapl, simple preprocessor based on source code is not enough. E.g. consider the following template source code: `@{Runtime r = Runtime.getRuntime();... r.exit(1)}`. It's hard for the template engine to do static analysis on the code and prevent the last statement `r.exit(1)`. A runtime security mechanism is needed I think – Gelin Luo Nov 22 '12 at 01:19

3 Answers3

2

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.

ShyJ
  • 4,560
  • 1
  • 19
  • 19
1

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.

Community
  • 1
  • 1
Jatin
  • 31,116
  • 15
  • 98
  • 163
1

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).

Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305
  • Hi thanks for your input. Can you give me some links to help me better understand how to implement SecurityManager with ClassLoader as you suggested in this context? – Gelin Luo Nov 25 '12 at 21:48