Restrict native code functionality from Java
I have a java application which uses JNI in some parts to do some work. It follows the usual loading of DLL and then calling native methods of DLL. Is there any way we can restrict what native methods can do from the java application? For example, can we restrict DLLs not to open any files or not to open any sockets even if it has the code to do it开发者_如何学JAVA? It can just forbid DLLs it loads for doing certain things, may be by loggin something or throwing an exception.
No you can't. The DLL gets loaded as a whole and then the Java side has no control on what the native code is doing.
One solution might be kind of man in the middle approach. This would involve coding a "shell" DLL that has the same interface as the original DLL. You tell Java to load a "shell" DLL for instance by putting it in a specific location and using the java.library.path
property. Then the role of the "shell" DLL is to load the "true" DLL by sandboxing it and redirecting standard functions. This sounds like a lot of pain and this something that would happen in the native side on things, not from Java.
Edit 2021: today it's also relevant to point out that the sandbox to run Java in would likely be a virtual machine, in the cloud, Docker or what have you, in a locked down configuration.
I liked Gregory Pakosz' answer a lot. However, what you could do is sandbox the Java instance itself. Start the Java application itself in a restricted context.
In Windows or Unix you can create a user which is limited to a certain directory and only has access to some DLLs. Thus the DLL called from JNI can do whatever it wants, but it will not get very far, because the user the Java runs as can not do very much.
If your Java program needs to do privileged things, the Java side of it will have to talk to another program (Java or not) to do its' privileged things for it.
Just keep in mind, that if you can not trust the DLL, you can no longer trust the Java code either, since the DLL might have "hacked" the Java machine. On the other hand, no nasty stuff should be able to break out of the limits of the user they run as. (Barring misconfiguration or a bug in the OS.)
Normally you would run your application under the Java security Manager but I don't believe it has any effect on code running through the JNI.
You could implement some kind of setting that your JNI code could get. For example, on an UNIX system, you could create groups for special types of privileges, and check if the current user has the required privileges, else just return 0 or something.
精彩评论