Skip to content

Java Programming

Security Requirements of a Java Application

Securing an application now a days is not an easy task.  To secure an application there are steps that we can take to mitigate the risk of security failures. In Java, security of an application is related to running our application under some protection of a security manager. To do this we must have a good knowledge of best practices to give ourselves an advantage over inadvertent system failures.

Java provides us a security manager class that extends java.lang.SecurityManager. Security manager is a class that allows Java applications to implement a security policy. This class allows an application to determine, before performing a possibly unsafe operation, what the operation is and whether it is being attempted in a security context that allows the operation to be performed. The application can allow or disallow the operation. SecurityManager class contains many methods that begins with the work check and these methods are called by various methods in the Java libraries before those methods perform certain operations. We can invoke these methods in the following way :

SecurityManager security = System.getSecurityManager();

if (security != null) {

security.checkXXX(argument, …);

}

Security manager in java gives us an opportunity to prevent an operation being completed by throwing an exception. A security manager routine simply returns if the operation is permitted, but if the operation is not permitted then SecurityException is thrown. The only exception to this convention is checkTopLevelWindow, which returns a Boolean. We can set the current security manager by calling the setSecurityManager() methods in class System and is obtained by calling the method getSecurityManager() method. SecurityManager class provides a special method

 {@link SecurityManager#checkPermission(java.security.Permission)}

which determines whether an access request indicated by a specified permission should be granted or denied. The default implementation is as follows:

AccessController.checkPermission(perm);

public void checkPermission(Permission perm) {

        java.security.AccessController.checkPermission(perm);

    }

Throws a Security Exception if the requested access specified by the given permission is denied or is not permitted based on the security policy currently in effect. The checkPermission method with just a single permission argument always performs security checks within the context of the currently executing thread.

Sometimes we need to add a security check that should be made within a given context, needed to be done from within a different context (for example, from within a worker thread). Security manager class is used to check certain application actions for permission during runtime. Once we have application or actions under the control of a security manager, the application can perform actions that are allowed by an associated security policy. By default policy is defined or specified in a plain text file named policy file. Operations that can be performed includes writing files to specific directories, writing system properties, and making network connections to specific hosts, etc. to run a Java application under a security manager you need a simple JVM command line option and you can create a policy file with any text editor. Editing such a security policy file and adding various rules of interest is not difficult but getting the policy right is more challenging. In order to achieve this we can use tools to help us understand what that policy should be.

JavaSecurity

 

The Default Java Security Manager

Java code we see written, discussed, and invoked represents the application that does not run subject to a security manager. Such applications have full access to all machine resources, including disk, network, and application shutdown. Such broad access can be easily restricted. We can force a Java application to run under the default Java security manager simply by setting the -Djava.security.manager option on the command line.

For example let us take a simple application, designed to read and print the user’s home directory

public class AccessHome {    public static void main(String[] argv) {       System.out.println(System.getProperty(“user.home”));    } }

Compile the code and run it subject to the default security manager

$ cd $HOME/Projects/CustomSecurityManager  $ javac AccessHome.java  $ java -Djava.security.manager AccessHome Exception in thread “main” java.security.AccessControlException:  access denied (java.util.PropertyPermission user.home read) … at AccessHome.main(AccessHome.java:5)

In the above code the application fails to acquire and print the user.home property, and we omitted most of the stacktrace for readability. The application fails to execute because the default security manager running with the default security policy deny accessing the property user.home. This privilege must be granted explicitly in a runtime policy file.

Creating a policy file policy.txt containing the single rule

grant codeBase “file:/home/project/Projects/CustomSecurityManager/”{    permission java.util.PropertyPermission “user.home”, “read”; };

and rerunning the application with a reference to that policy file solves the problem of read access to user.home:

$ java -Djava.security.policy=policy.txt -Djava.security.manager AccessHome  /home/project

We can refer the JVM to the policy file by setting the system property java.security.policy=policy.txt.

The rule in the policy.txt file permits any code contained in a file in that directory to read system property user.home. As a result, the rule allows AccessHome to run as intended. The file in which code is contained is termed a codebase. A codebase is therefore a class or jar file.

A Security Policy Profiler: ProfilingSecurityManager

Creating a security policy file is not difficult, even though utilities like policytool are also available and we have syntax shortcuts allowed in the policy file that are quite powerful, allowing the creation of very expressive, efficient rules.

So our aims are: Firstly we are interested in running our application subject to a security policy. Secondly, we want a programmatic method of determining those needs.

In order to achieve these aims we introduce the custom security manager secmgr.ProfilingSecurityManager. This class extends java.lang.SecurityManager, but does not enforce a security policy. It reports what that security policy would be if the application were granted access to everything it requests at runtime.

To use ProfilingSecurityManager, we need to first compile and strategically place it in its own jar file. Placing ProfilingSecurityManager alone in its own jar file will allow us to filter and suppress rules that arise from actions originating in its own jar file codebase. ProfilingSecurityManager is aware of its own unique codebase due to the following:

if( url.toString().equals(thisCodeSourceURLString) ) {    return null; }

and can therefore prevent reporting on itself. Compile and jar the tool:

$ mkdir -p classes lib  $ rm -rf classes/* lib/*  $ javac -d classes ProfilingSecurityManager.java  $ jar cf lib/psm.jar -C classes secmgr/manager  $ rm -rf classes/secmgr/manager

We can activate ProfilingSecurityManager by setting system property: -Djava.security.manager=secmgr.ProfilingSecurityManager, this will write to System.out the rules needed in a policy file that in turn will allow the application to run without throwing security violation exceptions

Running a simple AccessHome application with ProfilingSecurityManager specified as the security manager and with the rules output processed by parsecodebase.pl produces

$ java -cp .:lib/psm.jar -Djava.security.manager=secmgr.ProfilingSecurityManager AccessHome > raw.out   $ parsecodebase.pl < raw.out > policy.txt  $ cat policy.txt grant codeBase “file:/home/project/Projects/CustomSecurityManager/” {    permission java.util.PropertyPermission “user.home”, “read”; };  $ java -cp . -Djava.security.manager -Djava.security.policy=policy.txt AccessHome  /home

ProfilingSecurityManager satisfies both our design goals and aims:

  • Our application runs under a security manager with a well-defined application-specific policy
  • We specified or determined policy programmatically.

Hope this tutorial helped you to have a basic understanding of Java security application requirement. Please share your views in the comments section.

Be Sociable, Share!
    The following two tabs change content below.

    Basant Singh

    Basant is a talented software developer who is very engaged in web & cloud platforms on a daily basis. He is a contributor to codingthis.com reporting on various news and troubleshooting on various platforms. Basant is very strong in SQL and a great asset to the CodingThis community.

    Latest posts by Basant Singh (see all)