A recent question on SO lead me to an older answer about the Java Security Manager. My question about this line in that answer:
The security manager impacts performances though, and it is rarely used on the server side.
Can someone please back this up or refute? I thought there is always a security manager, a custom one or the default and that containers use it all the time.
In server-side code that you yourself write, I can't think for any need for you to use a SecurityManager, since if you are writing the code to perform some operation in your application, it's unlikely that you need to check if your code has the permissions that you have given it.
For instance, a lot of the methods in SecurityManager are related to IO operations - checkDelete(), checkRead(), checkWrite(), etc. The JDK library classes will call these methods when you try to create/write/read/delete a file, so calling them yourself would be pointless.
So it's unlikely that your server-side code would make much use of the SecurityManager. However, the code that your code runs in - if you are deployed in a servlet container for instance - might make use of these methods, because they are interested in determining if your code has some level of permission that they give it.
Related
Following a conversation on another question, an interesting issue is being raised.
Classes loaded with a security manager are protected with the corresponding security. This security could disable reflection (for example).
The question is: is it possible to break a security manager with sun.misc.unsafe? If yes, how?
EDIT
Changed SecuredClassLoader to Security Manager in question.
No. The sun.misc.Unsafe class requires an access check just like any other privileged action. You can block it with a custom class loader or security manager. Here's a simple example with an empty security manager that shows it'll throw an AccessControlException:
System.setSecurityManager(new SecurityManager());
Unsafe unsafe = Unsafe.getUnsafe();
What is "secure class loader"? SecureClassLoader? It is not secure, despite its name. All it does is limits the class loading source to a specific code location.
Therefore you don't even need any unsafe operations to "break" that. Just, for instance, make sure a replacement hacked class is in the classpath before SecureClassLoader even got the control.
Someone in that thread told you already -- you cannot have a secured spot in unsecured environment. If your code is deployed to a user machine, user is God there, and no JVM security can help you simply because JVM is a tiny layer on top of much more powerful native things.
The idea is to utilize AOP for designing applications/tools to debug/view execution flow of an application at runtime. To begin with, a simple data(state) dump at the start and end of method invocation will do the necessary data collection.
The target is not application developers but high level business analyst or high level support people for whom a execution flow could prove helpful. The runtime application flow can also be useful in reducing the learning curve of an application for new developers especially in configuration loaded systems.
I wanted to know if there already exists such tools/applications which could be used. Or better, if this makes sense, then is there a better way to achieve this.
You could start with Spring Insight (http://www.springsource.org/insight) and add your own plugins to collect data appropriate for business analysts/support staff. If that doesn't meet needs, you can write your own custom aspects. It is not that hard.
You could write your own aspects, as suggested by ramnivas, but to prepare for the requests from the users, you may want to just have the aspects compiled into the application, so that you don't have to take a hit at run-time, and then they could just select which execution flows or method groups they are interested in, and you just call the server and set some variable to give them the information desired.
Writing the aspects is easy, but to limit recompiling, you may want to get an idea what the users will want, for example, if they want to have a log of every call made from the time a webservice is called until it gets to the database, then you can build that in, but it would be easier to know this up-front.
Otherwise the aspect does nothing, if the variable is not set, and perhaps unset the variable when finished.
You could also have where they can pick which type of logging and for which user, which may lead to more useful information.
I need to create environment to run potentially untrusted code. Program allowed to connect to preconfigured address:port and nothing else (even read the system time). I have compiled the class whitelist. I'd searched similar questions, but found only template that based on SecurityManager which AFAIK is deprecated.
Can anybody give me a simple sample how to run code in sandbox based on security policies and AccessController?
As far as I know it's still SecurityManager that runs the security checks. But it seems to delegate to the AccessController nowadays.
First you'll need to switch on the security manager:
-Djava.security.manager
If you omit this argument there'll be no sandbox whatsoever.
Second you'll need to tell where to find the policy file:
-Djava.security.policy=
This will add your permissions to the ones already defined in your java home. The original sandbox rules in .../jre/lib/security/java.policy. However, if you want your policy to be the only one you'll need to use a double "=". This way you control completely what's allowed.
For example:
-Djava.security.policy==
I would advise you to use the "policytool" shipped with the Java. It's fairly basic but it helps you to write quickly a policy file with the correct syntax.
I hope this helps...
Can I avoid third party code from creating new threads, starting new VMs, or leaking data using a customized SecurityManager?
Thread creation results in a call to securityManager.checkAccess(g) where g is a ThreadGroup. That in turn requires SecurityConstants.MODIFY_THREADGROUP_PERMISSION.
The only way to create a new JVM instance is to start a new process. That will require SecurityConstraints.FILE_EXECUTE_ACTION.
So, if your SecurityManager raises an exception for both of those permissions, your first 2 cases are covered.
You'll need to qualify what constitutes "leaking data". Is the concern over accidental or deliberate leaks? Is the concern the untrusted code accessing data, or the untrusted code's data being accessible by other threads, classes, etc?
Nothing much is a full security solution (unless you ask salesmen).
I'd say the SecurityManager can control all this (as was said you don't necessarily need a custom security manager, you can configure a lot simply through a policy). Controlling threads, process execution, enforcing access to private data and network connections (3rd party app sending private data to your competition, etc) - that's what the SecurityManager is for.
However, you need to weigh how much security you need. Consider that with every Java security update Sun fixes maybe 3-4 vulnerabilities (Java 6u15 as an example) in the Java security sandbox. These updates take place about 3-4 times per year (or took, don't know what the Oracle acquisition will do to that). So any of these ~12 annual vulnerabilities could cause your data to be leaked.
If my secrets were very valuable to someone else, I personally would not trust SecurityManager to control potentially malicious 3rd party code running in my environment. (I don't have valuable secrets and I already don't trust Java running in my browser under the SecurityManager to behave.)
You can certainly do the first two things. However, i'm not sure what you mean by "leaking data".
Note, you don't need a customized SecurityManager, you just need a custom policy file.
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