Author Archives: Vishal Chougule

Reflection Proofing the Java Singleton Pattern when using Lazy Loading

The singleton design pattern in Java is one that I found over the years to be both tricky and interesting. There are many ways to break this pattern – and developers keep writing about different techniques to break it. One powerful way to break this pattern is to use reflection to access the private constructor and instantiate the class as many times as you want. The underlying idea is that you can call private members of any class using theAccessibleObject.setAccessible(true) reflection method.

There are available techniques to prevent such reflection attacks. One of them is using the old way of writing your Singleton class, that is, not using lazy initialization, and, in addition to that, throwing an exception in the constructor if it’s asked to create a second instance. Any client attempting to illegally execute the constructor after an instance is created will be thrown an exception. Listing 1 below illustrates this:

Listing 1: JavaSingleton class


package server;

public class JavaSingleton {
  private static final JavaSingleton INSTANCE = new JavaSingleton();
  private JavaSingleton() {
    if (INSTANCE != null) {
      throw new IllegalStateException("Inside JavaSingleton(): JavaSingleton " +
                                                        "instance already created.");
    }
    System.out.println("Inside JavaSingleton(): Singleton instance is being created.");
  }
  public static final JavaSingleton getInstance() {
    return INSTANCE;
  }
}

Listing 2: JavaSingleton client


import server.JavaSingleton;
import java.lang.reflect.*;

public class TestSingleton {
  public static void main(String[] args) throws ReflectiveOperationException {
    System.out.println("Inside main(): Getting the singleton instance using getInstance()...");
    JavaSingleton s = JavaSingleton.getInstance();

    System.out.println("Inside main(): Trying to use reflection to get another instance...");
    Class<JavaSingleton> clazz = JavaSingleton.class;
    Constructor<JavaSingleton> cons = clazz.getDeclaredConstructor();
    cons.setAccessible(true);
    JavaSingleton s2 = cons.newInstance();

  }
}

When you run this client, you will get following output:


C:\singleton>java TestSingleton
Inside main(): Getting the singleton instance using getInstance()...
Inside JavaSingleton(): Singleton instance is being created.
Inside main(): Trying to use reflection to get another instance...
Exception in thread "main" java.lang.reflect.InvocationTargetException
  at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
  at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
  at java.lang.reflect.Constructor.newInstance(Unknown Source)
  at TestSingleton.main(TestSingleton.java:13)
Caused by: java.lang.IllegalStateException: Inside JavaSingleton(): JavaSingleton instance already created.
  at server.JavaSingleton.<init>(JavaSingleton.java:7)
  ... 5 more

Nice stuff! But there’s one that noticeable here. This technique is possible only with early initialization, and not while using lazy initialization.

Lazy initialization, also known as on demand initialization, is often a requirement for reducing start up time of an application.

I wanted to write a singleton that addresses both the requirements of lazy initialization and defending against an attack in which a client creates a second a instance of the singleton.

My knowledge of Java Security gained while working on Websphere came in handy.

A Possible Use Case for this Requirement

Suppose we have a Java based service, in which clients get an instance via the getInstance() method, and we’d like to protect against multiple instances being created to avoid concurrency or memory related issues. Also, the start-up time needs to be short, so the method described above won’t work. The reason is that if we are throwing an exception in the constructor, we’d need to be certain that the first call to the constructor comes from within the class, or else the single instance could belong to a wrong class.

Design for the Reflection-Proof Lazily Initialized Singleton

  1. Allow ONLY the same class to access the constructor: We’ll need to do two things for this:
    1. Add code in the constructor that checks to see if the caller has access
    2. Create a policy file that defines which callers have access.
  2. There is one more thing, however. The Java Security Mechanism will check for the caller permissions for all callers present in the entire stack trace. Because of this, we need to wrap the call to our constructor in a doPrivleged block so that permissions are checked only from that point itself.

Modified Code for Lazy Initialization and Reflection Access Checks

Listing 3: Server JavaSingleton class

package server;

import java.lang.reflect.ReflectPermission;
import java.security.*;


public class JavaSingleton {

  private static JavaSingleton INSTANCE = null;
  private static int count = 0;

  private JavaSingleton() {
    ReflectPermission perm = new ReflectPermission("suppressAccessChecks", "");
    AccessController.checkPermission(perm); 
    ++count;
    System.out.println("Singleton Constructor Running. Instance #" + count);
  }


  synchronized public static final JavaSingleton getInstance() {
    if (INSTANCE == null) {
      AccessController.doPrivileged(new PrivilegedAction<Object>() {
        public Object run() {
          INSTANCE= new JavaSingleton();
          return null;
        }
      });
    }
    return INSTANCE;
  }

}//end of class

Listing 4: Client class

import java.lang.reflect.*;
import server.JavaSingleton;
 
 
public class TestSingleton {

  public static void main(String[] args) throws ReflectiveOperationException {
    System.out.println("Using getInstance...");
    JavaSingleton s = JavaSingleton.getInstance();

    System.out.println("Trying to use reflection to instantiate Java Singleton...");
    Class<JavaSingleton> clazz = JavaSingleton.class;
    Constructor<JavaSingleton> cons = clazz.getDeclaredConstructor();
    cons.setAccessible(true);
    JavaSingleton s2 = cons.newInstance();      
  }//end of main

}//end of class

Policy File Changes and Invocation

Creating a policy file

  1. Start the policy tool present in your JDK bin folder, and click “Add Policy Entry”Policy tool - first screen
  2. Enter the path to your Singleton class in the code base, the format of a URL. Do not include the package folder, and make sure your client classes reside in a different folder. For example, “file:/C:/singleton/server_code/”.CodeBase in policy tool
  3. Click “Add Permission” and select ReflectPermission from the Permission drop down and then select suppressAccessChecks from the Target Name drop down, and click OK.Permission added in policy tool for supressAccessChecks
  4. Click DonePolicy tool after adding permission
  5. Click File->Save, and provide a file name like singleton.java.policy

Your file should look similar to the following:

/* AUTOMATICALLY GENERATED ON Sun Nov 06 22:05:42 AST 2011*/
/* DO NOT EDIT */

grant codeBase "file:/C:/singleton/server_code/" {
  permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
};

Important: Keep the client and server code in separate code bases, otherwise the client code will have reflective access to the server code that it shouldn’t have. I placed the client class file in C:/singleton, and the server class files in C:/singleton/server_code. That is, the two server class files were present in C:/singleton/server_code/server (since they are in the “server” package).

Invoking the program

Invoke the program using a VM arg that specifies the location of the policy file:

C:\singleton>java  -cp .;server_code -Djava.security.policy=file:/C:/singleton/singleton.java.policy TestSingleton
Using getInstance...
Singleton Constructor Running. Instance #1
Trying to use reflection to instantiate Java Singleton...
Exception in thread "main" java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
        at java.lang.reflect.Constructor.newInstance(Unknown Source)
        at TestSingleton.main(TestSingleton.java:15)
Caused by: java.security.AccessControlException: access denied ("java.lang.reflect.ReflectPermission" "suppressAccessChecks")
        at java.security.AccessControlContext.checkPermission(Unknown Source)
        at java.security.AccessController.checkPermission(Unknown Source)
        at server.JavaSingleton.<init>(JavaSingleton.java:14)
        ... 5 more

Looking at the above output, we can see that our malicious client was denied access when trying to call the constructor directly. Thus, this example illustrates how we can implement a singleton that uses lazy initialization and protects against reflective attacks.

References