이번 장은 객체 직렬화를 다룬다. 객체 직렬화란 자바가 객체를 바이트 스트림으로 인코딩하고(직렬화) 그 바이트 스트림으로부터 다시 객체를 재구성하는(역직렬화) 매커니즘이다. 직렬화된 객체는 다른 VM에 전송하거나 디스크에 저장한 후 나중에 역직렬화할 수 있다. 이번 장은 직렬화가 품고 있는 위험과 그 위험을 최소화하는 방법에 집중한다.
[아이템 85] 자바 직렬화의 대안을 찾으라
[아이템 85] 자바 직렬화의 대안을 찾으라.
자바의 역직렬화에는 치명적인 단점이 있습니다. 신롸할 수 없는 스트림을 역직렬화하면 원격 코드 실행, 서비스 거부 등의 공격으로 이어질 수 있습니다.
역직렬화 폭탄이란 서비스 거부 공격을 유발하는 스트림입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
static byte [] bomb () {
Set < Object > root = new HashSet <>();
Set < Object > s1 = root ;
Set < Object > s2 = new HashSet <>();
for ( int i = 0 ; i < 100 ; i ++) {
Set < Object > t1 = new HashSet <>();
Set < Object > t2 = new HashSet <>();
t1 . add ( "foo" ); // t1을 t2와 다르게 만든다
s1 . add ( t1 ); s1 . add ( t2 );
s2 . add ( t1 ); s2 . add ( t2 );
s1 = t1 ;
s2 = t2 ;
}
return serialize ( root );
}
이 코드는 끝날 기미가 보이지 않는다. HashSet 인스턴스를 역직렬화 하려면 원소들의 해시코드를 계산해야 하는데 위 코드에서는 hashCode 메서드를 2^100번 넘게 호출해야합니다.
이러한 문제를 해결하는 가장 좋은 방법은 사용하지 않는 것입니다. 자바 직렬화보다 훨씬 간단하고 문제를 회피할 수 있는 방법으로 JSON과 프로토콜 버퍼가 대표적으로 있습니다.