In our application, users are able to define Java expressions that are executed by our main engine (those expressions are method calls only: e.g., Math.abs(42) ). They're executed via reflection.
What are the different solutions to prevent those expressions calling for example System.exit (but as well File access and others...) either directly or via a method call that will internally call eventually System.exit ?
Note that several different expressions can be executed in different threads. Preventing for example File access with a SecurityManager does not work as the main engine must still be able to access the File system while the expressions are executed.
You are wrong to say you can't use the SecurityManager -- this is precisely what it's for: hosting untrusted code, as in an Applet container or RMI server. The modern SecurityManager is configured with policy files that grant specific, fine-grained rights, including limited access to the file system. You need to use the SecurityManager, but you need to become an expert in it.
This is an enormous topic; the best thing to do would be to Google "Java security policy files" and just read everything you can.
What you are doing is crazy. Allowing users to execute arbitrary Java code on your machine is an awful idea and there is no way you can make that safe against Hackers who know their stuff.
The only solution I can think of is to create a whitelist of packages and methods that may be used. But trying to blacklist specific actions will never get you there. There is always someone who is smarter than you are when it comes to breaking stuff.
Update: I have now read more about the SecurityManager and it seems that you can controll package access very finely with it, so I'd suggest you to go with Ernest's answer.
The Java security system is the appropriate tool for this. SecurityManager is only a part of this system which you will have to use.
Basically you do not invoke the untrusted code yourself. Instead you will wrap that call into a PrivilegedAction and give that to one of the AccessController.doPrivileged methods. Then the untrusted code will be executed in another ProtectionDomain.
So you have to configure two protection domains: One for your engine with full privileges and one for the untrusted code with reduced privileges.
But as Ernest already mentioned: This is quite complicated stuff and not suited to a Q&A site like this. Read up the appropriate tutorials from Oracle and Co. Use the above keywords for your search.
For example Apache Velocity had a similar problem to solve. They use black listed classes and packages defined in velocity.properties:
# ----------------------------------------------------------------------------
# SECURE INTROSPECTOR
# ----------------------------------------------------------------------------
# If selected, prohibits methods in certain classes and packages from being
# accessed.
# ----------------------------------------------------------------------------
introspector.restrict.packages = java.lang.reflect
# The two most dangerous classes
introspector.restrict.classes = java.lang.Class
introspector.restrict.classes = java.lang.ClassLoader
# Restrict these for extra safety
introspector.restrict.classes = java.lang.Compiler
introspector.restrict.classes = java.lang.InheritableThreadLocal
introspector.restrict.classes = java.lang.Package
introspector.restrict.classes = java.lang.Process
introspector.restrict.classes = java.lang.Runtime
introspector.restrict.classes = java.lang.RuntimePermission
introspector.restrict.classes = java.lang.SecurityManager
introspector.restrict.classes = java.lang.System
introspector.restrict.classes = java.lang.Thread
introspector.restrict.classes = java.lang.ThreadGroup
introspector.restrict.classes = java.lang.ThreadLocal
There are too many things in Java which could cause a problem that you might not be aware of. The safest thing to do is to create a list of classes which are allows and run these via a custom class loader in a separate process (so you can kill it safely)
For serious dangerous code which most people don't even know is there have a look at sun.misc.Unsafe which allows you to
Access random areas of memory.
Create new instance of classes without calling a constructor e.g. new instances of Enums.
lock and unlock an objects monitor discretely. (Without a synchronized block)
Related
I am writing a plugin of another large java program .
I want to modify some byte code of some java method of the java program during runtime, so that I can intercept the method calls (namely, inject some hooking code into the method).
Any way can achieve this?
PS:
I've checked the following approaches:
1.change the classloader of the java program. (we CANNOT change it)
2.use java proxy. (We CANNOT use java proxy, because java proxy would create a new proxy object. We DON'T use the proxy object. We need to hook the java program's object, and Use that object)
3. use -javaagent option ( we CANNOT add the commandline option for the java program.)
PS more [Edited again]:
My classes was loaded by ext class loader (I put my jar files in JAVA_HOME\lib\ext folder).
The large java program is an applet program loaded by Browser. When the browser start the applet, it also loads my classes.
PS more more [Edited again]:
Although it's running in Applet. I can have full permission. Because I can modify java.policy and java.security file.
Thanks,
Calvin
Just use -javaagent opiton, which is used to modify the bytecode at runtime. You can find more about -javaagent from This Link or from This Link
There are several libraries which you can use. See for example here.
Once a class was already loaded/initialized by the VM it will be impossible to manipulate, though.
By the way, in principle you can also just replace the class to be 'hooked' with your own proxy class file. As long as the class' visible interface does not change this may work. (Sub-classes of the class may horribly fail at runtime though.) This replacement can be as easy as changing the classpath so that your class of the same name will be found first, before the original one. Delegating to the original class of the same name may be a little more complex in this case.
Yes, you can, but the process would be a bit tricky, as you would operate directly with memory. For this purpose, you'd look at unofficial documentation on sun.misc package and its Unsafe class.
Warning 1: the Unsafe class would be removed in JDK 9 according to official sources.
Warning 2: the Sun company would not take responsibility for your code to work correctly, as this class should not be used at all, and exists for system usage only.
Sorry, but this is not possible. First off, bytecode is immutable after classloading. The JVM provides several APIs that can be used to do something like this, but they are obviously highly privileged.
If you're running in a low privilege environment like a browser Applet, then you're obviously not going to be allowed to do this, and any method you could should be considered a security vulnerability.
But the question is why you are using applets in the first place, and why you want to modify code after loading. There's almost certainly a better way to do what you're trying to do.
I am wondering how one can attack the problem of denying *.groovy files the ability to reference and make use of certain classes that i pick. One approach is of course to install a security manager and classloader to block attempts toload or execute certain methods on certain classes eg java.io.File. This however of course from what i can imagine not affect interpretted mode as no class is ever generatd or loaded by the classloader.
Ideally i would like the equivalent of class verifying but for groovy files during the parsing phase and similar evaluations are executed.
Any pointers would be appreciated.
Not sure, but I believe the SecureASTCustomizer might help you (Groovy 1.8)
There is a blog post by Cedric Champeau which shows how it is used. Basically, you can set up a blacklist or whitelist of classes, imports, operators, etc that a script is allowed to use. Or indeed you can set more complex rules (see the examples on the blog post about debying variable names that start with a caps char, or denying the use of System.exit)
Also have a look at the java-sandbox library: http://blog.datenwerke.net/2013/06/sandboxing-groovy-with-java-sandbox.html
All,
I'm working on the design of a cloud-based service that will provide the option to execute some "plugin" code submitted by clients. In order to make this work it is essential that the plugins can't threaten system integrity or have any ability to access the data of other clients.
Ideally I'd like it to be possible for clients to submit a simple jar file (containing a class conforming to some pre-defined interface) which would then be run within a sandbox.
The client code should be allowed to:
Take as much CPU time as it needs on a single thread
Perform any calculations using standard java classes (e.g. java.lang.Math, java.util.Random etc.)
Call any libraries bundled in the jar (but which must be subject to the same restrictions)
But I would specifically need to disallow the following:
Spawning new threads (so that server resource can be fairly managed!)
Any access to the file system / IO / network
Any access to native code
Any access to data in the JVM other than that passed to / created by the client code
Any access to reflection on classes other than those in the .jar sandbox
Any ability to call methods on objects outside the sandbox, other than the standard Java libraries
Is it be possible to achieve this with a custom ClassLoader / SecurityManager setup? Or will I need to start looking for a more sophisticated solution (e.g. launching multiple JVMs?)
Managing resource and limiting resources is not possible in java. You can prevent malicious code to access system resources (disk/network and so) or the JVM itself but:
...
Spawning new threads (so that server resource can be fairly managed!)
If i wanna be malicious I am gonna do all my code in the finalizer thread and just block the VM. Same doing protected void finalize(synchronized(Thread.class) {for(;;) LockSupport.park();}} bye-bye new threads.
Eating all the memory, eating all direct memory and so on.
Accessing zip files in my own jar, and expect 'em getting moved away, so the JVM crashes (due to bug(s) in zlib)
If one purposely wants to deny resources, it is just not a feasible task to try and catch the hacker. You'd need to know what to search for and dynamically check/enhance the classes on run-time to disallow the behavior.
Any ability to call methods on objects outside the sandbox, other than the standard Java libraries
What are the standard libraries? Do you know if/when they must possibly execute some code in a privileged method.
Each customer - separate VM w/ full restrictions, process affinity/priority, incl max memory/stack and so on.
I think everything you want to achieve can be done through a custom SecurityManager. In fact it's pretty simple, you just create a class that extends SecurityManager, implement the two checkPermission(..) methods and in the first iteration just throw an SecurityException for everything that comes in (and log what you just denied). Then you allow specific operations until you find yourself in the situation that it's possible to create useful plugins and let your clients play with it. They will complain. Then you have to judge whether to allow them to do whatever they requested or if you want to stick with your rules. Here the difficult part begins...
Suppose I have a class in my package org.jake and it has a method with default access (no modifier). Then the method is visible inside the package only.
However, when someone receives the jar of my framework, what is to stop them from writing a new class, declaring its package as org.jake, and using my supposedly invisible method?
In other words, is there anything I can do to prevent this?
You could seal the package in your jar file. It's not bullet-proof though.
The main thing is not to rely on access modifiers etc from a security point of view to start with, really. If someone is running the code with unrestricted permissions, they're going to have access to all kinds of things. Access modifiers really just help to stop people from accidentally shooting themselves in the foot.
If someone is willing to put classes in your package to circumvent your encapsulation, they're clearly ignoring your best intentions - I say let 'em get on with it, but don't provide support for that scenario.
There is nothing you can do to prevent this. Even private members can be accessed via reflection. You should consider the access modifiers in java to be merely suggestive.
First off, this is the “DRM” scenario: ultimately, someone determined enough can defeat any protections you put in place by supplying a funky modified runtime or other such things. The reverse scenario – where the runtime is trusted but some of the packages are not – is tackled properly by Java through the use of suitable ClassLoader restrictions, but that can only work where there's something that can enforce the restrictions in a trusted fashion; that's why your scenario is basically doomed.
However, if we assume that the runtime itself is trustable then you could try, in your super-secret method, getting the stack trace of the currently executing stack (see stackoverflow.com/questions/1069066/… for how) and testing to see whether the caller of the current method is one that you trust to get access. A security manager would be even more suitable, but you can't trust the environment to have one of those installed that you like (it's much more clearly under the control of the attacker). Note that I have not tried the options in this paragraph!
The other alternative is to put your secrets on a service you control and only offer remote access to them. Or stop worrying about using technical mechanisms to deal with a problem that is fundamentally about business and legal issues (e.g., why are you dealing with people you can't trust?)
I'd say simply do not allow them to run code where it can call yours, i.e. in the same JVM. You could instead consider offering only a (web)service they can call externally. I'm not very up to date on the best ways to implement this though.
I need to call some semi-trustworthy Java code and want to disable the ability to use reflection for the duration of that code's execution.
try{
// disable reflection somehow
someObject.method();
}
finally{
// enable reflection again
}
Can this be done with a SecurityManager, and if so, how?
Clarification/Context: This is a follow-up to another question about restricting the packages that can be called from JavaScript/Rhino. The accepted answer references a blog entry on how to do that, and it requires two steps, the first one using a Rhino API (ClassShutter), the second one turning off reflection and Class.forName(). I was thinking I can do that second step more cleanly using a SecurityManager (learning about SecurityManager, which as has been pointed out, is a complex beast, along the way).
To sum up, I want (from code, not setting file) to turn off Class.forName() and any access to the whole reflection package.
It depends on what you are trying to restrict.
In general, publicly accessible API is not restricted. However, as long as you don't grant the untrustworthy code the ReflectPermission("suppressAccessChecks") permission, it won't be able to get access to non-public API in another package.
If you have a list of packages to which you want to restrict all access, there are two steps. First, in the Security properties, include the restricted package in the package.access list. Then give your trusted code RuntimePermission("accessClassInPackage." + pkg).
A common way to distinguish your untrusted code is to load it from a different location, and refer to the different codebases in your policy file when granting permissions.
The Java security architecture is very powerful, but I know it is also complicated; if you would like a more concrete example, please describe exactly what calls you want to restrict and I'll try to be more explicit.
To do what you want without modifying the java.policy file and/or the java.security file would be very difficult, maybe impossible. The java.security.Policy represents the information in java.policy, but it doesn't offer write access. You could create your own Policy implementation and install it at runtime as long as any existing SecurityManager permits it.
On the other hand, you can specify a custom java.policy file as a command-line option. If you are providing a complete application with some sort of launcher, that might be easily accomplished. It also provides some transparency to your users. A sophisticated user can review the permissions you'd like to have granted to the application.
Well, you can override SecurityManager.checkMemberAccess and give a stricter definition. However, it doesn't really work like that. What happens for instance if the code defines a finaliser?
On the clarification: Other APIs use reflection and other APIs. For instance, java.beans, LiveConnect and Rhino. An adversary could from within a script, say, create a new Rhino context without the shutter and thereby bootstrap into the full JRE. With an open system, a blacklist can never be finished.
In summary: to use the Java security model you need to work with it, not against it.
I wrote a replacement of ClassShutter that allows fine grained access control, per instance, per method, per field:
http://riven8192.blogspot.com/2010/07/java-rhino-fine-grained-classshutter.html