85. 자바 직렬화의 대안을 찾으라
"승리하는 유일한 길은 전쟁하지 않는 것이다." 자바 직렬화는 그 전쟁이다. 사용하지 않는 것이 최선이다.
📌 핵심 요약
🔥 자바 직렬화(Java Serialization) 는 보안, 성능, 유지보수 면에서 매우 위험하다.
🚫 신규 시스템에서는 사용을 지양하고, JSON, Protocol Buffers 등 크로스-플랫폼 구조화된 데이터 표현을 대안을 채택하라.
🔒 레거시 시스템에서 불가피하게 사용해야 한다면, →
ObjectInputFilter
를 활용한 역직렬화 필터링을 반드시 적용하라.😈 신뢰할 수 없는 데이터는 절대 역직렬화하지 말라
🧠 필수 개념
Serialization
객체 → 바이트 스트림으로 변환
Deserialization
바이트 스트림 → 객체로 복원
Serializable
직렬화 가능 클래스임을 표시하는 마커 인터페이스
readObject()
역직렬화 시 실행되는 위험한 메서드
⚠️ 자바 직렬화의 위험성
ObjectInputStream.readObject()
는 클래스패스 내 거의 모든 타입의 객체를 생성할 수 있다.이 과정에서 가젯(Gadget) 이라 불리는 악의적인 메서드 실행이 가능하다.
또한, 짧은 바이트 스트림만으로도 서비스 거부(DoS) 공격이 가능한 역직렬화 폭탄이 존재한다.
📎 예제: 역직렬화 폭탄
// 코드 85-1 역직렬화 폭탄 - 이 스트림의 역직렬화는 영원히 계속된다.
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); // 간결하게 하기 위해 이 메서드의 코드는 생략함
}
이 구조는 2ⁱ⁰⁰ 수준의
hashCode()
연산을 유도 → 역직렬화가 영원히 끝나지 않음
🔄 대안: 구조화된 데이터 표현
JSON
텍스트 기반, 가독성 높음, 거의 모든 언어에서 지원
Protocol Buffers
이진 기반, 성능 우수, 스키마 기반, 구글 개발
둘 다 단순하고 안전한 구조의 데이터를 주고받음
자동 객체 그래프 직렬화 X → 보안 취약점 제거
크로스 플랫폼, 높은 호환성, 커뮤니티 활발
🛡 자바 직렬화가 필요한 경우
신뢰할 수 없는 데이터는 절대 역직렬화하지 마세요 ❌
ObjectInputFilter
를 활용한 필터링 적용 (Java 9+)ObjectInputFilter filter = ObjectInputFilter.Config.createFilter("com.example.*;!*"); ObjectInputStream ois = new ObjectInputStream(inputStream); ois.setObjectInputFilter(filter);
화이트리스트 방식 추천 → 알려진 안전한 클래스만 허용
SWAT(Serial Whitelist Application Trainer) 도구로 필터 자동 생성 가능
📚 자바 버전별 변화
🏷️ Java 9부터
ObjectInputFilter
정식 지원🔄 이전 버전에서는 백포트 라이브러리 사용 가능
✅ 필터링은 역직렬화 폭탄, 메모리 초과 등도 일부 방어 가능
✍️ 느낀 점
직렬화는 단순한 기술이 아니라 위험한 기능이란 걸 알게 되었습니다. JSON이나 protobuf 같은 대안 사용이 필수이며, 레거시 시스템에서도 최소한의 방어책은 적용해야 합니다.
📌 반드시 알아야 할 점
⚠️ 자바 직렬화는 보안상 매우 취약하므로 신중히 사용해야 합니다.
✅ 새로운 시스템은 JSON / Protocol Buffers로 설계하세요.
🔐 레거시 시스템에서는:
신뢰할 수 없는 데이터는 역직렬화 금지
ObjectInputFilter
필수 적용화이트리스트 기반 필터링 권장
🔄 위험 징후 발견 시 패치 및 마이그레이션 계획 수립 필수
📖 직렬화 폭탄, 가젯 체인 공격 사례를 꼭 학습하고 대비하세요.
🧾 결론
자바 직렬화는 사용하지 않는 것이 가장 안전한 선택입니다.
구조화된 데이터 표현(JSON, protobuf 등)은 더 안전하고, 호환성도 뛰어나며, 관리도 쉬움.
부득이한 경우에도 철저한 필터링과 검증이 필요합니다.
Last updated