Can one break a secury manager with sun.misc.unsafe? - java

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.

Related

Controlling access to loading of a JAVA class at runtime

I have a requirement to restrict access to loading of a particular class of a JAVA application, at runtime. Just wondering whether this is possible using JAVA Security Manager with a security policy. Also, if this is a possibility, I'd like to know how the permission configuration would look like in a JAVA security policy. I'd done some researching on this but couldn't really find any useful solution yet.
These two:
java.security.Permission
java.io.FilePermission
and providing you need to continue the application operating in some way without it you need to load classes using java.lang.ClassLoader and loadClass method to be able to throw it into an if-else to bypass potentially if simple instantiation is not involved.
I managed to come up with a custom permission implementation extending java.security.RuntimePermission class and get my requirement fulfilled. The only overhead (which is unavoidable) associated with the approach of introducing a custom permission is that, you need to hack into all your classloading implementations and add an additional check to evaluate your custom permission.

Security manager rarely used on server?

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.

Java: danger in setting private member field as accessible?

To set the value of a private Field, it needs to be marked as accessible:
field.setAccessible(true);
When will the SecurityManager not allow this? How portable is it to include this in a library? Will it fail when imported into certain contexts?
If you know your library won't be used inside a JVM with the Security Manager enabled, like an applet or a secured application server, then it's fine. But I would try to avoid it if possible.
There are others answers like this link that suggest there's no problem using it. So if you think it's the best approach, and the other options are too cumbersome or directly don't exist, then go ahead.
When will the SecurityManager not allow this?
The javadoc says:
First, if there is a security manager, its checkPermission method is called with a ReflectPermission("suppressAccessChecks") permission.
A SecurityException is raised if flag is true but accessibility of this object may not be changed (for example, if this element object is a Constructor object for the class Class).
As to your other question
How portable is it to include this in a library? Will it fail when imported into certain contexts?
It is portable across JVM implementations because Field is defined in the core library with these semantics. It is not portable across instances because different JVM instances may have differently configured security policies.

Create java sandbox based on security policies

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

Is SecurityManager a full security solution?

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.

Categories

Resources