How to Set SecurityManager and Java Security Policy Programmatically

In this example I want to show how to use SecurityManager to prevent unauthorized access to private members of a Java class, for example using reflection to invoke private constructor. Besides that I also want to show how Java security policy can be set programmatically with permission allowing to invoke private constructor through reflection when security manager is in place.

Consider a POJO:

public final class VictimClass  {
	/**
	 * Private constructor that should
	 * not be invoked
	 */
	private VictimClass()  {
	   System.out.println("Instance created");
           System.out.println(
               "Constructor was made accessible");
	}
}

I want to prevent invocation of private constructor, by setting security manager. After first invocation attempt, I do want to invoke private constructor by granting required permission by refreshing current security policy.

This is my tester class:

import java.lang.reflect.Constructor;
import java.lang.ClassNotFoundException;
import java.lang.InstantiationException;
import java.lang.IllegalAccessException;
import java.lang.reflect.InvocationTargetException;
import java.lang.NoSuchMethodException;
import java.security.AccessControlException;
import java.lang.reflect.ReflectPermission;
import java.security.SecurityPermission;

public class Tester  {

	private static String CLASS_NAME = "VictimClass";
	private static Class victimClass = null;

	public static void main(String[] args)  {

	loadClass(victimClass, CLASS_NAME);

	//apply default policy with one permission
	System.setProperty("java.security.policy","default.policy");

	try {
	  //Setting security manager
	  SecurityManager sm = new SecurityManager();
	  System.setSecurityManager(sm);
	} catch (SecurityException e) {
	  System.err.println("Error: could not set security manager: " + e);
	}

	//first attempt to make constructor accessible
	try  {
	  makeConstructorAccessible();
	}
	catch (AccessControlException e) {
	  System.err.println(
		"Could not made constructor accessible: " + e.getMessage());
	}

	System.out.println("Applying ReflectPermission programmatically...");
	SecurityPolicy.getPolicy().addPermission(
		new ReflectPermission("suppressAccessChecks"));
	SecurityPolicy.getPolicy().addPermission(
		new SecurityPermission("setPolicy"));
	SecurityPolicy.getPolicy().refresh();
	makeConstructorAccessible();
	}

private static void loadClass(Class clazzor, String className)  {
	Thread thread = Thread.currentThread();
	ClassLoader classLoader =
				thread.getContextClassLoader();

	try {
	 victimClass = Class.forName(className, true, classLoader);
	}
	catch (ClassNotFoundException e) {
	 System.err.println("Error: could not find class: "
			+ CLASS_NAME);
	}
}

private static void makeConstructorAccessible()  {
	Constructor[] constructors =
			victimClass.getDeclaredConstructors();
	//make constructor accessible
	constructors[0].setAccessible(true);

   try {
	System.out.println(
	"Creating new instance by invoking private constructor");
	constructors[0].newInstance(new Object[] {});
   }
	catch (InstantiationException e) {
	  System.err.println("Error: could not instantiate: " + e);
	}
	catch (IllegalAccessException e) {
	  System.err.println("Error: could not access: " + e);
	}
	catch (InvocationTargetException e) {
	  System.err.println("Error: could not invoke the target: " + e);
	}
  }
}

This is what happens when program executes:

Before setting SecurityManager, I am applying default security policy from external file with security permission “setPolicy”, that will allow me to reset new security policy in the future.

My default security policy:

grant {
	permission java.security.SecurityPermission "setPolicy";
};

When SecurityManager is set, it restricts everything except whats permitted by security policy that was set previously. You can view list of Java permissions that can be set here.

By default, the private constructors,methods and fields are inaccessible. So if you want to use reflection, and invoke private constructor of this POJO, it will result in
IllegalAccessException since the constructor above has private modifier.

This restriction can be bypassed by calling parent method setAccessible(). To remind: java.lang.reflect.Constructor, java.lang.reflect.Method and java.lang.reflect.Field extend from parent java.lang.reflect.AccessibleObject class.

By calling inherited parent method setAccessible(), private variables and methods including private constructors become accessible.

With SecurityManager set, an attempt to invoke setAccessible() will result in AccessControlException. Following that, I am granting required ReflectPermission suppressAccessChecks by applying my own security policy. This will allow me to invoke private constructor in my POJO.

Now, having said that, I have to say that granting ReflectPermission with action suppressAccessChecks can be extremely dangerous as it allows private constructors to become accessible, as the example above shows. Not only constructors, but inaccessible fields and methods can become accessible, which can allow room for reflection attacks. In my other post Hack any Java class using reflection attack I explain how this can be achieved.

When I am applying my own security policy, please note that I am granting again security permission “setPolicy”. Because I am reseting default policy set previously, I have to grant “setPolicy” permission again if I want to keep applying new security policies in the future at run time of this program.

Below is my own implementation of java.security.Policy class, I tried to put enough comments to make things straight forward to you readers:

import java.security.Policy;
import java.security.CodeSource;
import java.lang.reflect.ReflectPermission;
import java.security.SecurityPermission;
import java.security.*;
import java.lang.RuntimePermission;
import java.util.*;

public class SecurityPolicy extends Policy {

	private PermissionCollection perms = null;

    //lazy initialization class holder
    private static class SecurityPolicyHolder {
	private static final SecurityPolicy policy = new SecurityPolicy();
    }

    private SecurityPolicy() {
	perms = new Permissions();
    }

    public static SecurityPolicy getPolicy() {
	return SecurityPolicyHolder.policy;
    }

    public PermissionCollection getPermissions(CodeSource codesource) {
        return perms;
    }

    //invoked when new Permission is added to the current security Policy
	public boolean implies(ProtectionDomain domain, Permission permission)  {

	//get permission collection from the domain
	PermissionCollection domainPermissions = domain.getPermissions();

	//get enumeration of permission elements
	Enumeration<Permission> permissions = domainPermissions.elements();

	//convert to array list (dont have to, i just dont like enumerations)
	ArrayList<Permission> list = Collections.list(permissions);

	//Checks to see if the specified permission is
	//implied (subset of) by the collection of
	//Permission objects held in this PermissionCollection
	if (!domainPermissions.implies(permission)) {

		//permission collection in the domain is read-only,
		//Exception will be thrown if Permission object
		//is added to read-only collection
		if (domainPermissions.isReadOnly()) {

			//Because collection is read-only,
			//add Permission objects to the local
			//permission collection instead
			for (Permission p :list) {
				if (!perms.implies(p)) {
				   perms.add(p);
				}
			}

			//assign local permission collection as a
			//domain permission collection
			domainPermissions = perms;
		}
		else {
			//if domain permission collection is not read only,
			//just add new permission to it
		  domainPermissions.add(permission);
		}

		//check if now domain has the new Permission
		return domainPermissions.implies(permission);
	}

		return false;
	}

	public void addPermission(Permission permission)  {
        perms.add(permission);
	}
        //you can write your own implementation
	//of refresh method
        @Override
	public void refresh() {
         Policy.setPolicy(this);
	}
}

The following shows program output. Please not that first attempt to make private constructor accessible resulted in exception. After required permission was granted, new object instance was succesfully created through reflection:

Could not made constructor accessible:
access denied (java.lang.reflect.ReflectPermission suppressAccessChecks)
Applying ReflectPermission programmatically...
Creating new instance by invoking private constructor
Constructor was made accessible
Instance created

Please note:
I did test this code. But I am not sure whether my SecuriyPolicy class implemented efficiently. The source code for this post is attached.

set java security policy sourcecode