티스토리 뷰

직렬화란?

  • 자바가 객체를 바이트 스트림 으로 인코딩하고(직렬화) 그 바이트 스트림으로부터 다시 객체를 재구성하는 (역직렬화) 메커니즘이다.

직렬화의 단점

  • 직렬화의 근본적인 문제는 공격 범위가 너무 넓고 지속적으로 더 넓어져 방어하기 어렵다는 점이다
  • 바이트 스트림을 역직렬화하는 과정에서 readObject 메서드는 그 타입들 안의 모든 코드를 수행할수 있다
  • 신뢰할 수 없는 스트림을 역직렬화 하면 원격 코드 실행(remote code execution), 서비스 거부(denial-oof-service)등의 공격으로 이어질수 있다
  • 가젯 메서드
    • 역직렬화 과정에서 호출되어 잠재적으로 위험한 동작을 수행하는 메서드
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 메서드를 엄청 호출

대안

  • 직렬화 위험을 회피하는 가장 좋은 방법은 아무것도 역직렬화 하지 않는 것이다
  • JSON과 프로토콜 버퍼로 대체 가능하다
    • JSON은 텍스트 기반이라 사람이 읽을수 있다
    • 프로토콜 버퍼는 이진표현이라 효율이 훨씬 높음
  • 직렬화를 피할 수 없고 역직렬화한 데이터가 안전한지 완전히 확신할 수 없다면 객체 역직렬화 필터링(java.io.ObjectInputFilter)을 사용하자(자바 9에 추가되었고, 이전 버전에서도 쓸 수 있도록 이식되었다.)
  • 객체 역직렬화 필터링은 데이터 스트림이 역직렬화 되기 전에 필터를 설치하는 기능이다. 클래스 단위로, 특정 클래스를 받아들이거나 거부할 수 있다.
  • '기본 수용' 모드에서는 블랙 리스트에 기록된 잠재적으로 위험한 클래스들을 거부한다.
  • '기본 거부' 모드에서는 화이트리스트에 기록된 안전하다고 알려진 클래스들만 수용한다.
  • 블랙리스트 방식보다는 화이트리스트 방식을 추천한다. 블랙리스트 방식은 이미 알려진 위험으로부터만 보호할 수 있기 때문이다. 여러분의 애플리케이션을 위한 화이트리스트를 자동으로 생성해주는 스왓(SWAT) 이라는 도구도 있으니 참고하자.

필터링 기능은 메모리를 과하게 사용하거나 객체 그래프가 너무 깊어지는 사태로부터도 보호해준다. 하지만 앞서 보여준 직렬화 폭탄은 걸러내지 못한다.

핵심 정리

직렬화는 위험하니 피해야 한다. 시스템을 밑바닥부터 설계한다면 JSON이나 프로토콜 버퍼 같은 대안을 사용하자. 신뢰할 수 없는 데이터는 역직렬화하지 말자. 꼭 해야 한다 면 객체 역직렬화 필터링을 사용하되, 이마저도 모든 공격을 막아줄 수는 없음을 기억하
자. 클래스가 직렬화를 지원하도록 만들지 말고, 꼭 그렇게 만들어야 한다면 정말 신경 써서 작성해야 한다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함