readObject메서드를 호출하면 객체 그래프가 역직렬화 되기 때문에, 클래스안의 거의 모든 타입의 객체를 만들어 낼 수 있는 마법같은 생성자이다.
하지만 유효성 검증이 어려워 보안에 문제가 있으며, 보이지 않는 생성자
라고 불린다.
일반 생성자
//양수를 저장하는 클래스
public class PositiveNumber implements Serializable {
public final int value;
public PositiveNumber(final int value) {
this.value = value;
//양수 validation검증 필요
if (this.value < 0) {
throw new RuntimeException();
}
}
}
validation 로직을 적용하여, 객체가 생성될때 유효성을 검증할 수 있다.
readObject
//PositiveNumber 객체를 직렬화하는 함수
private byte[] getSerialzedObject(int value) throws IOException{
byte[] serializedObject;
try(ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream)){
PositivieNumber positiveNumber = new PositiveNumber(value);
ojbectOutputStream.writeObject(positiveNumber);
serializedObject = byteArrayOutputStream.toByteArray();
}
}
byte[] serializedObject = getSerialzedObject(1); //양수로 정상 초기화 + 직렬화
//악의적인 사용자가 해당 값을 변경할 경우
serializedObject[43] = -1;
serializedObject[44] = -1;
serializedObject[45] = -1;
serializedObject[46] = -1;
//역직렬화
try(ByteArrayInputStream byteArrayInputStream = new ByteArrayInpuutStream();
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream)){
PositivieNumber positiveNumber = (PositiveNumber) objectInputStream.readObject();
objectOutputStream.writeObject(positiveNumber);
positiveNumber.value; // -1 이 나옴
}
readObject가 validation로직을 포함하지 않기 때문에, 유효성을 만족하지 않는 객체의 생성을 막을 수 없음