본문 바로가기
  • Where there is a will there is a way.
개발/java

자바 직렬화에 대한 생각정리

by 소확행개발자 2020. 7. 26.

언젠가 내가 개발하고 있는 클래스에 implements Serializable 이 되어있는 걸 확인했다. 해당 클래스는 jpa entity 였고 문서를 찾아본 결과 entity 에 붙어있었고 왜 붙였을까에 대한 인터넷 서칭을 해보았다.

“If an entity instance is to be passed by value as a detached object (e.g., through a remote interface), the entity class must implement the Serializable interface.”
따라서, 이 객체를 어딘가로 전송하거나 세션에 기록하거나 등등 정말 serialization을 위한 용도가 아니라면,
Hibernate상에서는 굳이 Serailizable을 구현하지 않아도 된다는 뜻이지만,
사람들은 흔히 권하기를 그래도 웬만하면 Serializable을 구현하는 것이 좋은 습관일 것이라고 권한다.

라고 명시되어있는 글을 보았다. 권한다 ? 위에서도 설명되어 있지만 해당 엔티티를 어딘가로 전송하거나 세션에 기록하거나 할때 serialization 을 한다는 건 알겠다. 하지만 웬만하면 Serialization 을 구현하는 것에 대해서는 의문이 생겼다. 정말 그게 맞을까 ?

( https://everydayminder.wordpress.com/2013/07/10/entity-%EB%AA%A8%EB%8D%B8-%EA%B0%9D%EC%B2%B4%EB%8A%94-serializable%EC%9D%84-%EA%BC%AD-%EA%B5%AC%ED%98%84%ED%95%B4%EC%95%BC-%ED%95%98%EB%82%98/ )

 

effective java 에 나와있는 이야기를 해보려고 한다. 

 

과연 자바 직렬화는 안전한가? 

다음은 우아한 형제들의 블로그에 담겨있는 역직렬화의 예제이다. 

여기서 ObjectInputStream 의 readObject 메서드를 호출하면서 객체 그래프가 역직렬화 되는데, 클래스패스 안의 거의 모든 타입의 객체를 만들어 낼 수 있다고 한다. ( 해당 메소드가 )

 

다른 라이브러리에 클래스들도 해당 공격범위에 포함되어서 만약 우리의 직렬화 가능 클래스들을 공격에 대비하도록 작성한다 해도, 우리의 애플리케이션은 여전히 취약할 수 있다. 또한 잘못된 코드는 역직렬화 할때 메서드 호출에 심각한 문제가 생겨서 ( 오랫동안 역직렬화 한다고 표현하면 맞으려나 ) 깊이 제한에 걸리고 버그 신호조차 받지 못하는 위험성을 초래할 수 있다. 

 

effective java 책에서 말하는 해결책은 직렬화의 위험을 회피하려면 아무것도 직렬화를 사용하지 않는다 이다. 위에서 말햇듯이 세션에 기록하거나 할 때 말고는 자바 직렬화를 써야 할 이유는 전혀 없다. 

 

블랙리스트 보다는 화이트리스트 방식을 추천한다. 

 

만약에 implement serializable 을 구현하려면 신중히 결정해야 한다. 

 

구현은 위와 같이 선언만 하면 간단하지만 릴리스한 뒤에는 수정하기 어렵다. 클래스가 Serializable 을 구현하면 직렬화된 바이트 스트림 인코딩도 하나의 공개 API 가 된다. 그래서 이 클래스가 널리 퍼진다면 그 직렬화 형태도 영원히 지원해야 하는 것이다. 

 

물론 이를 해결하기 위해서 serialVersionUID 라는 이름의 static final long 필드로 직접 명시해서 클래스에 넣어주기도 한다. 만약 이 번호를 명시하지 않으면 시스템이 런타임에 암호해시 함수를 적용해 자동으로 클래스 안에 생성해서 넣는다.

 

결과적으로 말하면 시리얼라이저를 붙이려면 신중해야 한다. 

 

 

'개발 > java' 카테고리의 다른 글

클래스와 멤버에 대해서  (0) 2020.07.27
객체의 생성  (0) 2020.07.09
빌더로 생성자 대체하기  (0) 2020.07.06
Iterator design pattern  (0) 2020.05.28
JPA 2차 캐시란  (0) 2020.04.26

댓글