Following the useful suggestions from @Leigh and @Miguel-F, I tried my hands on implementing the Security Manager
and Policy
. Here's the outcome:
1. Specifying an Additional Policy File at runtime instead of making changes to the default java.policy
file. To enable this, we add the following parameters to JVM arguments using CFAdmin interface or alternatively appending it to the jvm.args
line in the jvm.config
file :
-Djava.security.manager -Djava.security.policy="c:/policies/myRuntime.policy"
There is a nice GUI utility inside jre\bin\
called policytool.exe
which allows you to manage policy entries easily and efficiently.
2. We have enforced the Security manager and provided our custom security policy file which contains:
grant codeBase "file:///D:/proj/secTestProj/main/-"{
permission java.io.FilePermission
"<<ALL FILES>>", "read, write, delete";
};
Here we are setting FilePermission
for all files to read, write, delete
excluding execute
from the list as we do not want any type of file to be executed using the java runtime.
Note: The codebase can be set to an empty string if we want the policy to be applied to all the applications irrespective of the source.
I really wished for a deny
rule in policy file to make things easier similar to the grant
rule we're using, but there isn't unfortunately. If you need to put in place a set of complex security policies, you can use Prograde library, which implements policy file with deny rule (stack ref.).
You could surely replace <<ALL FILES>>
with individual file and set permissions accordingly or for a better control use a combination of <<ALL FILES>>
and individual file permissions.
References: Default Policy Implementation and Policy File Syntax, Permissions in JDK and Controlling Applications
This approach solves our core issue: denying execution of files using java runtime by specifying permissions allowed on a file. In other approach, we can implement Security Manager
directly in our application to define policy file from there, instead of defining it in our JVM args.
//set the policy file as the system securuty policy
System.setProperty("java.security.policy", "file:/C:/java.policy");
// create a security manager
SecurityManager sm = new SecurityManager();
//alternatively, get the current securiy manager using System.getSecuriyManager()
//set the system security manager
System.setSecurityManager(sm);
To be able to set it, we need these permissions inside our policy file:
permission java.lang.RuntimePermission "setSecurityManager";
permission java.lang.RuntimePermission "createSecurityManager";
permission java.lang.RuntimePermission "usePolicy";
Using Security Manager object inside an application has its own advantages as it exposes many useful methods For instance: CheckExec(String cmd)
which checks whether a calling thread is allowed to create a sub-process or not.
//perform the check
try{
sm.checkExec("notepad.exe");
}
catch(SecurityException e){
//do something...show warning.
}
CreateObject(Java)
function via the GUI or will that be too restrictive? What about the administrator setting under SettingsDisable access to internal ColdFusion Java components
? Did you check that. – BawdyCreateObject(Java)
was my first thought in the after math, but then there isCfObject
allowing the same functionality. And restricting both altogether would be indeed too much restrictive as they are used throughout the applications. If there is a way to disable only thetype=java
in both the cases, the issue will be solved. I am getting the feeling there might be someJVM arguments
that might allow this restriction. – Gavriellainternal ColdFusion Java Components
does not cover java native libraries and just only the ColdFusion implementation of them, for instance:Coldfusion.server.SystemInfo
, as per the short description given on theserver settings page
below the option, which says: "Disables the ability for CFML code to access and create Java objects that are part of the internal ColdFusion implementation." – GavriellaSecurity Manager
internals and how would it integrate with ColdFusion application. Found this answer which suggest using a custom java classloader, which gives only a fair enough idea to run your thoughts around. – GavriellaJava Security Manager
approach. First step would be to handle permissions allowed forjava.lang.Runtime
using thejava.lang.RuntimePermission
object OR the second approach as I see a little clear now would be to modifyjava.policy
file underjre/lib/security
and remove permission mentioned there for the Runtime & ProcessBuilder classes. I too have no idea of the impact the security policy changes would have on the ColdFusion server itself and the application code. But I am going for trail and learn approach now. Thanks! – Gavriella-Djava.security.manager "-Djava.security.policy=cf_root/WEB-INF/cfusion/lib/coldfusion.policy" "-Djava.security.auth.policy=cf_root/WEB-INF/cfusion/lib/neo_jaas.policy"
– Bawdy