Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: the last NCE should avoid nonstatic examples
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. 

Typically, the Singleton pattern uses a single instance of a class that encloses a {{private static}} instance 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 (nonprivate constructor)

This noncompliant code example uses a nonprivate 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}

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 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. 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. Compliant Solution (1) ({{readResolve}} method)

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 nontransient or nonstatic instance variables. This prevents the singleton from being indirectly serialized. 

If making a singleton class serializable is indispensable, ensure that only one instance of the class exists by adding a {{readResolve()}} method which can be made to return the original instance. The phantom instance obtained after deserialization is left to the judgment of the garbage collector. \[[Bloch 08|AA. Java References#Bloch 08]\]

{code:bgColor=#ccccff}
private Object readResolve() {
  return INSTANCE;
}
{code} 

If the serializable singleton class has any other instance fields, they must be declared {{transient}} to be compliant (described later in the nontransient instance fields noncompliant code example). 

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

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

{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 (nontransient instance fields)

This serializable noncompliant code example uses a nontransient 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"}; // nontransient 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. Compliant Solution (1) (transient fields)

This compliant solution declares the {{str}} instance field as {{transient}} so that it is not serialized.

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

h2. Compliant Solution (2) ({{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"}; // nontransient 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 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 nonstatic singleton is eligible for garbage collection when its object goes out of scope:

{code:bgColor=#FFcccc}
{
 MySingleton ms1 = MySingleton.getInstance();
 // ... 
}

MySingleton ms2 = MySingleton.getInstance(); 
{code}

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

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.  

{code:bgColor=#FFcccc}
TODO
{code}

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} this might need a different NCE {mc}

This problem can particularly manifest in state bearing singletons.

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 method. 

{code:bgColor=#ccccff}
{
  MySingleton ms1 = MySingleton.getInstance();
  ObjectPreserver.preserveObject(ms1);
  // ... 
}

MySingleton ms2 = (MySingleton) ObjectPreserver.getObject(); 
{code}

The {{ObjectPreserver}} class (based on \[[Patterns 02|AA. Java References#Patterns 02]\]) is shown below:

{code}
public class ObjectPreserver implements Runnable {
  private static ObjectPreserver lifeLine = new ObjectPreserver();
  
  // Neither this class, nor HashSet will be garbage collected.
  // References from HashMap to other objects will also exhibit this property
  private static final HashMap<Integer,Object> protectedMap = new HashMap<Integer,Object>();
  
  private ObjectPreserver() {
    new Thread(this).start();  // keeps the reference alive  
  }
 
  public synchronized void run(){
    try {
      wait();
    } catch(InterruptedException e) { /* Forward to handler */ }
  }

  // Objects passed to this method will be preserved until
  // the unpreserveObject method is called
  public static void preserveObject(Object obj) {    
    protectedMap.put(0, obj);  
  }
  
  // Returns the same instance every time
  public static Object getObject() {
    return protectedMap.get(0);	  
  }
  
  // Unprotect the objects so that they can be garbage collected
  public static void unpreserveObject() {
    protectedMap.remove(0);
  }
}

{code} 


h2. Risk Assessment

Using lazy initialization in a Singleton without synchronizing the {{getInstance()}} method may lead to creation of multiple instances and can as a result, violate the expected contract.
|| 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!|CON24-J. Use a unique channel to acquire locks on any file]