If I understand AccessController.doPrivileged correctly, it is saying that untrusted code should be able to invoke methods requiring permissions (such as System.getProperty()) through an intermediate method that does have permissions.
That brings up the question: when should AccessController.doPrivileged() be used? When should untrusted code be allowed to invoke privileged code through intermediate methods? When should it fail?
Following your reasoning, please explain why ClassLoader creation should always be allowed: http://findbugs.sourceforge.net/bugDescriptions.html#DP_CREATE_CLASSLOADER_INSIDE_DO_PRIVILEGED
Agree with Suraj's answer, but thought I'd add a specific example where I've required the use of a privileged block.
Imagine you've built an application that provides a number of services to pluggable modules. So your app and its services are trusted code. The pluggable modules, however, are not necessarily trusted and are loaded in their own class loaders (and have their own protection domains).
When a pluggable module invokes a service, you are implementing custom security checks ("does pluggable module X have permission to use this service"). But the service itself might require some core Java permission (read a system property, write to a file, etc). The code that requires these permissions is wrapped in a doPrivileged() so that the insufficient permissions from the untrusted pluggable modules are effectively ignored - only the privileges of your trusted services module apply.
..through an intermediate method that does have permissions . No, the final effective permissions is the intersection of all permissions in the domain stack. So suppose an operation requires a permission B to execute, and say some intermediate LIB has two permissions B and A. Now when some untrusted code with only permission A calls through LIB, the effective permission set is (A intersect (A+B)) = A. Hence the untrusted code cannot exploit intermediate LIB to gain extra permissions.
When should doPriveleged be used?-> There are lot of operations in Java that require the caller domain to have certain permissions for successful execution of those operations. System.getProperty is one of those operations. All file related operations also need special permissions. When you use AccessController.doPrivileged to invoke those operations, the operation is executed with all the rights(permissions) of your protection domain. Hence if your code has enough rights only then it could execute those operations.
Essentially, AccessController.doPriviledged() is the equivalent of a set-user-id file. It is saying "I hereby request that this method be done with my privileges, even if I was invoked by a method that does not have them."
Check out these links and scroll down to using the doPrivileged API.
Java 6:
http://docs.oracle.com/javase/6/docs/technotes/guides/security/doprivileged.html
Java 7:
http://docs.oracle.com/javase/7/docs/technotes/guides/security/doprivileged.html
When the AccessController checkPermission method is invoked by the most recent caller, the basic algorithm for deciding whether to allow or deny the requested access is as follows:
If the code for any caller in the call chain does not have the requested permission, AccessControlException is thrown, unless the following is true - a caller whose code is granted the said permission has been marked as "privileged" (see below) and all parties subsequently called by this caller (directly or indirectly) all have the said permission
Related
We use Javascript to communicate between an applet and its hosting web page. We need to modify the applet to include the permissions attribute, and would like to know which value is needed for enabling Javascript communication for the applet. Can we use sandbox or do we need to use all-permissions?
An applet scripted by Java Script only needs the same permissions as the applet would without Java Script.
Having said that, any call from JS is not considered 'trusted' by the JVM. So if a method that requires trust is called from JS, it will need to implement (in the code) use of doPrivileged(PrivilegedAction).
More on AccessController
The AccessController class is used for access control operations and decisions.
More specifically, the AccessController class is used for three purposes:
to decide whether an access to a critical system resource is to be allowed or denied, based on the security policy currently in effect,
to mark code as being "privileged", thus affecting subsequent access determinations, and
to obtain a "snapshot" of the current calling context so access-control decisions from a different context can be made with respect to the saved context.
More on PrivilegedAction
A computation to be performed with privileges enabled. The computation is performed by invoking AccessController.doPrivileged on the PrivilegedAction object. ..
Given the changing security regime, I would recommend wrapping all code that might ever be called from JS, into a PrivilegedAction.
I don't know if is you are looking for but for me it works if I deploy the applet with javascript:
http://docs.oracle.com/javase/tutorial/deployment/applet/invokingAppletMethodsFromJavaScript.html
sandbox will work fine, but if you want to acess files or sockets you'll need to configure java.policy file:
http://docs.oracle.com/javase/tutorial/security/tour1/wstep2.html
and grant permissions like java.security.Permission or java.io.FilePermission
I want to implement a system that allow user to add certain business logics.
I can use my own class loader to load it and create instance of this class.
It will extend my predefined interfaces and I will call some of it's methods.
How can I prevent it do something bad in my system? Bad thing I mean reading unneccessary files in my server, writing useless information or even dangerous information to my server.
It can visit some predefined external ip addresses(or predefined internal network)
Java has security management built in. If you are not familiar with it you should have a look at Security Features in Java tutorial which also shows what you have to do as "Code Receiver": http://docs.oracle.com/javase/tutorial/security/toolsign/receiver.html.
Also look into Java Security Architecture and Policy Files. The latter link contains these example from a policy file, so you can get an idea:
grant codeBase "file:/C:/somepath/api/" {
...
};
// If the code is signed by "Duke", grant it read/write access to all
// files in /tmp:
grant signedBy "Duke" {
permission java.io.FilePermission "/tmp/*", "read,write";
};
It means you can restrict (or rather grant specific) permissions to classes based on their origin.
Follow the links to the Michael's comment on your question to see some real world usage of Java's security architecture.
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)
It there a way to scope javax.crypto.Cipher calls within "trusted" part of the application? I would like to make sure cipher.init and cipher.doFinal happen only in "authorized" part of the program, so perhaps the fingerprint of these calls can be made a part of the key?
You might be able to use a policy file to enforce restrictions on certain methods: see http://download.oracle.com/javase/1,5.0/docs/guide/security/PolicyFiles.html for policy file detail. I'm not sure if the security manager can cover those methods though, but its worth trying.
You indicate you would like to include the call path in the key. You can trivially restrict the the creation of valid keys by including a unique private parameter when you call the privileged functions, and incorporate it into the key.
This will remove the dependency on the code structure, while still linking the calling location to the authorisation. Of course, you now have another key component to secure.
The native Policy implementation may well be sufficient if you can trust the application deployments not to be subverted.
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