item 85) 자바 직렬화의 대안을 찾으라
직렬화
개념
자바 시스템 내부에서 사용되는 객체 또는 데이터를 외부의 자바 시스템에서도 사용할 수 있도록 바이트(byte) 형태로 데이터 변환하는 기술과 바이트로 변환된 데이터를 다시 객체로 변환하는 기술(역직렬화)을 아우르는 것
시스템적으로 보면, JVM의 메모리에 상주(힙 또는 스택)되어 있는 객체 데이터를 바이트 형태로 변환하는 기술과, 직렬화된 바이트 형태의 데이터를 객체로 변환해서 JVM으로 상주시키는 형태를 이야기한다.
사용하는 이유
자바 시스템 개발에 최적화되어있어 복잡한 데이터 구조의 클래스의 객체라도 직렬화 기본 조건만 지키면 큰 작업 없이 바로 직렬화/역직렬화 가능하다.
데이터 타입이 자동으로 맞춰지기 때문에 이 부분에 대해 신경을 쓰지 않아도 된다.
프레임워크를 사용하지 않는 경우에는 CSV, JSON을 사용하는 것보다 편할 것 같다.
직렬화의 문제점
공격 범위가 너무 넓고, 지속적으로 더 넓어지기 때문에 방어하기 어렵다
readObject() 메서드는 Serializable 인터페이스를 구현한 클래스패스 안에 거의 모든 타입의 객체를 만들어 낼 수 있다. 바이트 스트림을 역직렬화하는 과정에서 이 메서드는 그 타입들 안의 모든 코드를 수행할 수 있고, 이로 인해 그 타입들의 코드 전체가 공격 범위에 들어가게 된다. (자바 표준 라이브러리와 서드 파티 라이브러리 등 모두 포함)
여러 가젯 메서드를 사용해 가젯 체인을 구성할 수 있으며, 강력한 가젯 체인은 시스템을 마비시키고 그로 인해 막대한 피해를 볼 수 있다.
가젯 메서드: 역직렬화 과정에서 호출되어 잠재적으로 위험한 동작을 수행하는 메서드
역직렬화 폭탄
역직렬화에 시간이 오래 걸리는 짧은 스트림을 역직렬화하는 스트림
아래 예시는 바이트 스트림으로 직렬화하는데는 시간이 별로 걸리지 않지만, 역직렬화시 hashCode 메서드를 2^100번 넘게 호출해야 하므로 영원히 계속된다.
여러 객체를 생성한다면 스택 깊이 제한에 걸려 프로그램에 장애가 발생할 것이다.
해결 방안
새로운 시스템에는 객체와 바이트 시퀀스를 변환해주는 다른 메커니즘이 많이 있기 때문에 직렬화 사용을 자제하는 것이 좋다.
신뢰할 수 없는 데이터는 절대 역직렬화하면 안된다. (역직렬화 폭탄)
크로스-플랫폼 구조화된 데이터 표현
cross-platform structured-data representation
자바 직렬화와 다른 메커니즘을 가진 객체와 바이트 시퀀스 변환 시스템
자바 직렬화의 위험성이 없으며 훨씬 간단하다.
다양한 플랫폼 지원, 우수한 성능, 풍부한 지원 도구 등을 제공
속성-값 쌍의 집합으로 구성된 간단하고 구조화된 데이터 객체를 사용
JSON
텍스트 기반 표현에 효과적이고 사람이 읽을 수 있다
프로토콜 버퍼
문서를 위한 스키마를 제공하며 효율이 좋다
역직렬화 필터링
데이터 스트림이 역직렬화되기 전에 필터를 설치하는 기능
블랙리스트에 기록된 클래스를 거부하거나, 화이트리스트에 기록된 클래스만 수용한다.
이미 알려진 위험으로부터만 보호할 수 있는 블랙리스트보다 화이트리스트를 사용하는 것이 좋다.
메모리를 과하게 사용하거나 객체 그래프가 너무 깊어지는 상황으로부터 보호한다.
역직렬화 폭탄은 걸러내지 못한다.
출처
Last updated