Reflection vulnerabilities and deserialization vulnerabilities in singleton patterns

Keywords: Programming Java

Reflection vulnerabilities and deserialization vulnerabilities in singleton patterns

In addition to the enumerative singleton mode, the remaining four are Singleton mode There are reflection vulnerabilities and deserialization vulnerabilities in the implementations of the mentioned singleton patterns.

package singleton;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;

/**
 * Solving Singleton Patterns by Reflection and Deserialization
 * @author weiyx15
 *
 */
public class SingletonCrack {
	public static void main(String[] args) throws Exception
	{
		// Normally create singleton objects
		SingletonLazy s1 = SingletonLazy.getInstance();
		SingletonLazy s2 = SingletonLazy.getInstance();
		System.out.println(s1);
		System.out.println(s2);
		
		// Solving a Single Case with Reflection
		Class<SingletonLazy> cls = (Class<SingletonLazy>) Class.forName("singleton.SingletonLazy");		// Get the SingletonLazy class
		Constructor<SingletonLazy> cons = cls.getDeclaredConstructor(null);		// Constructing Method for Obtaining Singleton Lazy
		cons.setAccessible(true);			// Visibility Check of Skipping Method
		SingletonLazy s3 = cons.newInstance();	// Call the constructor to generate a new object
		SingletonLazy s4 = cons.newInstance();	// Call the constructor to generate a new object
		System.out.println(s3);
		System.out.println(s4);
		
		// Solving singletons by deserialization
		FileOutputStream fos = new FileOutputStream("object.out");	// File Output Stream
		ObjectOutputStream oos = new ObjectOutputStream(fos);		// Object Output Stream
		oos.writeObject(s1);										// Serialize objects to files
		oos.close();												// Close object output stream
		fos.close();												// Close the file output stream
		
		FileInputStream fis = new FileInputStream("object.out");	// File input stream
		ObjectInputStream ois = new ObjectInputStream(fis);			// Object input stream
		SingletonLazy s5 = (SingletonLazy) ois.readObject();		// Deserializing objects from files
		ois.close();												// Close the object input stream
		fis.close();												// Close File Input Stream
		System.out.println(s5);
	}
}

Operation result

singleton.SingletonLazy@15db9742	// s1
singleton.SingletonLazy@15db9742	// s2
singleton.SingletonLazy@6d06d69c	// s3
singleton.SingletonLazy@7852e922	// s4
singleton.SingletonLazy@3b07d329	// s5

As can be seen from the running results, the private construction method can be obtained by reflection, which instantiates two different object instances {@code singleton.Singleton Lazy@6d06d69c} and {@code singleton.Singleton Lazy@7852e922}. New objects {@code singleton.Singleton Lazy@3b07d329} can also be obtained by deserialization.

Taking the implementation of lazy singleton pattern as an example, the methods to solve reflection and deserialization vulnerabilities are as follows:

package singleton;

import java.io.ObjectStreamException;
import java.io.Serializable;

/**
 * Lazy Singleton Model Eliminating Reflection Vulnerabilities and Deserialization Vulnerabilities
 * @author weiyx15
 *
 */
public class SingletonLazySafe implements Serializable{
	private static SingletonLazySafe instance;
	
	private SingletonLazySafe() {
		// Prevent reflection vulnerabilities by instantiating new instance s by calling private constructors again
		if (instance != null)
		{
			throw new RuntimeException();	// Throw a runtime exception
		}
	}
	
	public static synchronized SingletonLazySafe getInstance() {
		if (instance == null)	// If not instantiated, instantiate first
		{
			instance = new SingletonLazySafe();	// Instantiate the object after calling the getInstance method
		}
		return instance;
	}
	
	/**
	 * readResolve interface is called when reading an object from an I/O stream
	 * Return instance object directly in readResolve interface
	 * Avoid re-instantiating objects when deserializing
	 * @return Singleton object
	 * @throws ObjectStreamException
	 */
	private Object readResolve() throws ObjectStreamException {
		return instance;
	}
}

Posted by mad_hacker on Mon, 08 Apr 2019 09:45:30 -0700