Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Wiki Markup
The singleton design pattern's intent is succinctly described by the seminal work of Gamma et al. \[[Gamma 95|AA. Java References#Gamma 95]\]:

{quote}
Ensure a class only has one instance, and provide a global point of access to it.
{quote}

"Since there is only one Singleton instance, any instance fields of a Singleton will occur only once per class, just like {{static}} fields. Singletons often control access to resources such as database connections or sockets." \[[Fox 01|AA. Java References#Fox 01]\]. Other applications of singletons involve maintaining performance statistics, system monitoring and logging, implementing printer spoolers or as simple as ensuring that only one audio file plays at a time. Classes that contain only {{static}} methods are good candidates for singletons. 

Typically, the Singleton pattern uses a single instance of a class that encloses a {{private static}} class field. The instance can be created using _lazy initialization_, which means that the instance is not created when the class loads but when it is first used.

h2. Noncompliant Code Example (nonprivatenon-private constructor)

This noncompliant code example uses a non-private constructor for instantiating a singleton.

{code:bgColor=#FFcccc}
class MySingleton {
  private static MySingleton INSTANCE;

  protected MySingleton() {    
    // private constructor prevents instantiation by untrusted callers
    INSTANCE = new MySingleton();
  }

  public static synchronized MySingleton getInstance() {    
    return INSTANCE;
  }
}
{code}

A malicious subclass may extend the accessibility of the constructor from {{protected}} to {{public}}, allowing untrusted code to create multiple instances of the singleton. Also, the class field {{INSTANCE}} has not been declared as {{final}}.

h2. Compliant Solution ({{private}} constructor)

This compliant solution reduces the accessibility of the constructor to {{private}} and initializes the field {{INSTANCE}} immediately, allowing it to be declared {{final}}.

{code:bgColor=#ccccff}
class MySingleton {
  private static final MySingleton INSTANCE = new MySingleton();

  private MySingleton() {    
    // private constructor prevents instantiation by untrusted callers
  }

  public static synchronized MySingleton getInstance() {    
    return INSTANCE;
  }
}
{code}

The {{MySingleton}} class need not be declared as final because it has a private constructor.

h2. Noncompliant Code Example (visibility across threads)

When the getter method is called by two (or more) threads simultaneously, multiple instances of the {{Singleton}} class might result if access is not synchronized.

{code:bgColor=#FFcccc}
class MySingleton {
  private static MySingleton INSTANCE;

  private MySingleton() {    
    // private constructor prevents instantiation by untrusted callers
  }

  // Lazy initialization
  public static MySingleton getInstance() { // Not synchronized
    if (INSTANCE == null) {
      INSTANCE = new MySingleton();
    }
    return INSTANCE;
  }
}
{code}

h2. Noncompliant Code Example (inappropriate synchronization)

Multiple instances can be created even if the singleton construction is encapsulated in a {{synchronized}} block.

{code:bgColor=#FFcccc}
public static MySingleton getInstance() {
  if (INSTANCE == null) {
    synchronized (MySingleton.class) {
      INSTANCE = new MySingleton();
    }
  }
  return INSTANCE;
}
{code}

This is because two or more threads may simultaneously see the field {{INSTANCE}} as {{null}} in the {{if}} condition, and enter the synchronized block one at a time.

h2. Compliant Solution (1) ({{synchronized}} method)

To avoid the issue of multiple threads creating more than one instance of the singleton, make {{getInstance()}} a {{synchronized}} method.

{code:bgColor=#ccccff}
class MySingleton {
  private static MySingleton INSTANCE;

  private MySingleton() {
    // private constructor prevents instantiation by untrusted callers
  }

  // Lazy initialization
  public static synchronized MySingleton getInstance() {
    if (INSTANCE == null) {
      INSTANCE = new MySingleton();
    }
    return INSTANCE;
  }
}
{code}

h2. Compliant Solution (2) (double-checked locking)

Another compliant solution for implementing thread-safe singletons is the double-checked locking idiom.  

{code:bgColor=#ccccff}
class MySingleton {
  private static volatile MySingleton INSTANCE;

  private MySingleton() {
    // private constructor prevents instantiation by untrusted callers
  }

  // Double-checked locking
  public static MySingleton getInstance() {
    if (INSTANCE == null) {
      synchronized (MySingleton.class) {
        if (INSTANCE == null) {
          INSTANCE = new MySingleton();
        }
      }
    }
    return INSTANCE;
  }
}
{code}

This design pattern is often implemented incorrectly. Refer to [CON22-J. Do not use incorrect forms of the double-checked locking idiom] for more details on the double-checked locking idiom.

h2. Compliant Solution (3) (initialize-on-demand holder class idiom)

This compliant solution uses a {{static}} inner class to create the singleton instance.

{code:bgColor=#ccccff}
class MySingleton {
  static class SingletonHolder {
    static MySingleton INSTANCE = new MySingleton();
  }

  public static MySingleton getInstance() {
    return SingletonHolder.INSTANCE;
  }
}
{code}

This is known as the initialize-on-demand holder class idiom. Refer to [CON22-J. Do not use incorrect forms of the double-checked locking idiom] for more information.

h2. Noncompliant Code Example (Serializable singleton)

This noncompliant code example implements the {{java.io.Serializable}} interface which allows the class to be serializable. Deserialization of the class implies that multiple instances of the singleton can be created.

{code:bgColor=#FFcccc}
class MySingleton implements Serializable {
  private static final long serialVersionUID = 6825273283542226860L;
  private static MySingleton INSTANCE;

  private MySingleton() {
    // private constructor prevents instantiation by untrusted callers
  }

  // Lazy initialization
  public static synchronized MySingleton getInstance() {
    if (INSTANCE == null) {
      INSTANCE = new MySingleton();
    }
    return INSTANCE;
  }
}
{code}

A singleton's constructor cannot install any checks to enforce the requirement that the number of instances be limited to one because serialization provides a mechanism to bypass the object's constructor.

h2. Noncompliant Code Example ({{readResolve()}} method)

It is insufficient to add a {{readResolve()}} method that returns the original instance, to ensure the singleton property. This is insecure even if all the fields are declared {{transient}} or {{static}}. 

{code:bgColor=#FFcccc}
class MySingleton implements Serializable {
  private static final long serialVersionUID = 6825273283542226860L;
  private static MySingleton INSTANCE;

  private MySingleton() {
    // private constructor prevents instantiation by untrusted callers
  }

  // Lazy initialization
  public static synchronized MySingleton getInstance() {
    if (INSTANCE == null) {
      INSTANCE = new MySingleton();
    }
    return INSTANCE;
  }

  private Object readResolve() {
    return INSTANCE; 
  }
}
{code} 

At runtime, an attacker can add a class that reads in a crafted serialized stream:

{code}
public class Untrusted implements Serializable {
  public static MySingleton captured;
  public MySingleton capture;
  
  public Untrusted(MySingleton capture) {
    this.capture = capture;
  }

  private void readObject(java.io.ObjectInputStream in) throws Exception {
    in.defaultReadObject();
    captured = capture;
  }
}
{code}

The crafted stream an be generated by serializing the following class:

{code}
public final class MySingleton implements java.io.Serializable {
  private static final long serialVersionUID = 6825273283542226860L;
  public Untrusted untrusted = new Untrusted(this); // Additional serial field
 
  public MySingleton() { }
}
{code}

Upon deserialization, the field {{MySingleton.untrusted}} is reconstructed before {{MySingleton.readResolve()}} is called. Consequently, {{Untrusted.captured}} is assigned the deserialized instance of the crafted stream instead of {{MySingleton.INSTANCE}}. This issue is pernicious when an attacker can add classes to exploit the singleton guarantee of an existing serializable class.

h2. Compliant Solution ({{enum}} types)

It is recommended that stateful singleton classes be made non-serializable. As a precautionary measure, classes that are serializable must never save a reference to a singleton object in their non-transient or non-static instance variables. This prevents the singleton from being indirectly serialized. 

Bloch \[[Bloch 08|AA. Java References#Bloch 08]\] suggests the use of an {{enum}} type as a replacement for traditional implementations when serializable singletons are indispensable. 

{code:bgColor=#ccccff}
public enum MySingleton {
  INSTANCE;
  // Other methods
}
{code}

Functionally, this approach is equivalent to commonplace implementations and is safer. It ensures that only one instance of the object exists at any instant and also provides the serialization property as {{java.lang.Enum<E>}} extends {{java.io.Serializable}}.


h2. Noncompliant Code Example (non-transient instance fields)

This serializable noncompliant code example uses a non-transient instance field {{str}}.

{code:bgColor=#FFcccc}
class MySingleton implements Serializable {
  private static final long serialVersionUID = 2787342337386756967L;
  private static MySingleton INSTANCE;
  private String[] str = {"one", "two", "three"}; // non-transient instance field
                 
  private MySingleton() {
    // private constructor prevents instantiation by untrusted callers
  }

  public void displayStr() {
    System.out.println(Arrays.toString(str));
  }
 
  private Object readResolve() {
    return INSTANCE;
  }
}
{code}

"If a singleton contains a nontransient object reference field, the contents of this field will be deserialized before the singleton’s {{readResolve}} method is run. This allows a carefully crafted stream to "steal" a reference to the originally deserialized singleton at the time the contents of the object reference field are deserialized." \[[Bloch 08|AA. Java References#Bloch 08]\].

h2. Noncompliant Code Example (transient fields)

This noncompliant code example declares the {{str}} instance field as {{transient}} so that it is not serialized.

{code:bgColor=#FFcccc}
class MySingleton implements Serializable {
  // ...
  private transient String[] str = {"one", "two", "three"}; // non-transient field
  // ...
}
{code}

However, this is still insecure because of reasons described in the noncompliant code example ({{readResolve()}} method).

h2. Compliant Solution ({{enum}} types, non-transient fields)

This compliant solution uses the {{enum}} type to ensure that only one instance of the singleton exists at any time.

{code:bgColor=#ccccff}
public enum MySingleton {
  INSTANCE;
  private String[] str = {"one", "two", "three"}; // non-transient field
     
  public void displayStr() {
    System.out.println(Arrays.toString(str));
  }	 
}
{code}

h2. Noncompliant Code Example (Cloneable singleton)

It is also possible to create a copy of the singleton by cloning it using the object's {{clone()}} method if the singleton class implements {{java.lang.Cloneable}} directly or through inheritance. This noncompliant code example shows a singleton that implements the {{java.lang.Cloneable}} interface.

{code:bgColor=#FFcccc}
class MySingleton implements Cloneable {
  private static MySingleton INSTANCE;

  private MySingleton() {
    // private constructor prevents instantiation by untrusted callers
  }

  // Lazy initialization
  public static synchronized MySingleton getInstance() {
    if (INSTANCE == null) {
      INSTANCE = new MySingleton();
    }
    return INSTANCE;
  }
}
{code}

h2. Compliant Solution (override {{clone()}} method)

Avoid making the singleton class cloneable by not implementing the {{Cloneable}} interface or not deriving from a class that already implements it. 

If the singleton class indirectly implements the {{Cloneable}} interface through inheritance, override the object's {{clone()}} method and throw a {{CloneNotSupportedException}} exception from within it \[[Daconta 03|AA. Java References#Daconta 03]\].

{code:bgColor=#ccccff}
class MySingleton implements Cloneable {
  private static MySingleton INSTANCE;

  private MySingleton() {
    // private constructor prevents instantiation by untrusted callers
  }

  // Lazy initialization
  public static synchronized MySingleton getInstance() {
    if (INSTANCE == null) {
      INSTANCE = new MySingleton();
    }
    return INSTANCE;
  }

  public Object clone() throws CloneNotSupportedException {
    throw new CloneNotSupportedException();
  }
}
{code}

See [MSC05-J. Make sensitive classes noncloneable] for more details about restricting misuse of the {{clone()}} method.


h2. Noncompliant Code Example (garbage collection)

When the utility of a class is over, it is free to be garbage collected. This behavior can be troublesome when the program needs to maintain only one instance throughout its lifetime. 

A {{static}} singleton is garbage collected when its class loader becomes eligible for garbage collection. This usually happens when a nonstandard (custom) class loader is used to load the singleton. This noncompliant code example prints different values of the hashcode of the singleton object from different scopes. 

{code:bgColor=#FFcccc}
  {
    ClassLoader cl1 = new MyClassLoader();
    Class class1 = cl1.loadClass(MySingleton.class.getName());
    Method classMethod = class1.getDeclaredMethod("getInstance", new Class[] { });
    Object singleton = classMethod.invoke(null, new Object[] { });
    System.out.println(singleton.hashCode());
  }
  ClassLoader cl1 = new MyClassLoader();
  Class class1 = cl1.loadClass(MySingleton.class.getName());
  Method classMethod = class1.getDeclaredMethod("getInstance", new Class[] { });
  Object singleton = classMethod.invoke(null, new Object[] { } );
  System.out.println(singleton.hashCode());
{code}

{mc}
back-up code
  {
    ClassLoader cl1 = new FirstClassLoader();
    Class class1 = cl1.loadClass(MySingleton.class.getName());
    Method instanceMethod = class1.getDeclaredMethod("getInstance", new Class[] { });
    Object singleton = instanceMethod.invoke(null, new Object[] { } );
  }
  ClassLoader cl2 = new SecondClassLoader();
  Class class2 = cl2.loadClass(MySingleton.class.getName());
  Method instanceMethod = class2.getDeclaredMethod("getInstance", new Class[] { });
  Object singleton = instanceMethod.invoke(null, new Object[] { } );
	
{mc}

Code that is outside the scope can create another instance of the singleton class though the requirement was to use only the original instance.


{mc}
// The following class produces the same hashcode from different scopes, so is safe

public class StaticClass {
  public void doSomething() {
     {
       MySingleton ms = new MySingleton();
       Object singleton = ms.getInstance();
       System.out.println(singleton.hashCode());
     }
       MySingleton ms = new MySingleton();
       Object singleton = ms.getInstance();
       System.out.println(singleton.hashCode());
  }
  
  public static void main(String[] args) {
    StaticClass sc = new StaticClass();
    sc.doSomething();
  }
}
{mc}

h2. Compliant Solution (prevent garbage collection)

This compliant solution takes into account the garbage collection issue described above. A class is not garbage collected until the {{ClassLoader}} object used to load it becomes eligible for garbage collection. An easier scheme to prevent the garbage collection is to ensure that there is a direct or indirect reference from a live thread to the singleton object that needs to be preserved. 

This compliant solution demonstrates this technique and prints a consistent hashcode across all scopes.  It uses the {{ObjectPreserver}} class based on \[[Patterns 02|AA. Java References#Patterns 02]\] and described in [CON03-J. Do not use background threads during class initialization].

{code:bgColor=#ccccff}
  {
    ClassLoader cl1 = new MyClassLoader();
    Class class1 = cl1.loadClass(MySingleton.class.getName());
    Method classMethod = class1.getDeclaredMethod("getInstance", new Class[] { });
    Object singleton = classMethod.invoke(null, new Object[] { });
    ObjectPreserver.preserveObject(singleton); // Preserve the object
    System.out.println(singleton.hashCode());
  }
  ClassLoader cl1 = new MyClassLoader();
  Class class1 = cl1.loadClass(MySingleton.class.getName());
  Method classMethod = class1.getDeclaredMethod("getInstance", new Class[] { });
  Object singleton = ObjectPreserver.getObject();  // Retrieve the preserved object
  System.out.println(singleton.hashCode());
{code}


h2. Risk Assessment

Using improper forms of the singleton design pattern may lead to creation of multiple instances of the singleton and violate the expected contract of the class.

|| Rule || Severity || Likelihood || Remediation Cost || Priority || Level ||
| CON23- J | low | unlikely | medium | {color:green}{*}P2{*}{color} | {color:green}{*}L3{*}{color} |

h3. Automated Detection

TODO

h3. Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the [CERT website|https://www.kb.cert.org/vulnotes/bymetric?searchview&query=FIELD+KEYWORDS+contains+CON32-J].


h2. References

\[[JLS 05|AA. Java References#JLS 05]\] [Chapter 17, Threads and Locks|http://java.sun.com/docs/books/jls/third_edition/html/memory.html]
\[[Fox 01|AA. Java References#Fox 01]\] [When is a Singleton not a Singleton?|http://java.sun.com/developer/technicalArticles/Programming/singletons/]&nbsp;
\[[Daconta 03|AA. Java References#Daconta 03]\] Item 15: Avoiding Singleton Pitfalls;
\[[Darwin 04|AA. Java References#Darwin 04]\] 9.10 Enforcing the Singleton Pattern
\[[Gamma 95|AA. Java References#Gamma 95]\] Singleton
\[[Patterns 02|AA. Java References#Patterns 02]\] Chapter 5, Creational Patterns, Singleton
\[[Bloch 08|AA. Java References#Bloch 08]\] Item 3: "Enforce the singleton property with a private constructor or an enum type" and Item 77: "For instance control, prefer enum types to readResolve"
\[[MITRE 09|AA. Java References#MITRE 09]\] [CWE ID 543|http://cwe.mitre.org/data/definitions/543.html] "Use of Singleton Pattern in a Non-thread-safe Manner"

----
[!The CERT Sun Microsystems Secure Coding Standard for Java^button_arrow_left.png!|CON22-J. Do not use incorrect forms of the double-checked locking idiom]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[!The CERT Sun Microsystems Secure Coding Standard for Java^button_arrow_up.png!|11. Concurrency (CON)]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[!The CERT Sun Microsystems Secure Coding Standard for Java^button_arrow_right.png!|VOID CON24-J. Use a unique channel to acquire locks on any file]