flawopen.com/Java 역직렬화/ObjectInputStream 보안
ObjectInputStream은 신뢰할 수 없는 데이터에 안전한가요?
Java 보안 참고 자료
쉽게 설명하면
대체로 안전하지 않습니다. readObject()는 Java 객체를 복원하면서 클래스의 역직렬화 메서드를 실행할 수 있습니다. 첨부물이 자체 지침까지 실행하는 양식을 받는 것과 같습니다. 악성 스트림은 앱에 이미 포함된 클래스 동작에 도달할 수 있습니다. 실행 여부는 클래스, 라이브러리, 경로와 입력 경계에 달려 있으며 모든 호출에서 발생하지 않습니다.
위험: 네이티브 객체 역직렬화
// 공격자가 제어하는 바이트를 전달하지 마세요.
try (var in = new ObjectInputStream(untrustedStream)) {
Object value = in.readObject();
handle(value);
}
더 안전함: 고정 데이터 유형 파싱
// 신뢰할 수 없는 입력에는 광범위한 다형성 타입 지정을 끄세요.
ObjectMapper mapper = new ObjectMapper();
OrderRequest value = mapper.readValue(
untrustedBytes, OrderRequest.class
);
validate(value);
취약점이 도달 가능한 경로
API, 큐, 캐시 또는 파일 가져오기가 사용자 제어 바이트를 받습니다. ObjectInputStream.readObject()에 도달하면 JVM은 프로세스의 직렬화 가능 클래스로 객체를 복원합니다. gadget 체인은 기존 동작의 가능한 경로이지 모든 스트림에 들어 있는 페이로드가 아닙니다. Oracle은 CVE-2015-4852에서 지정 WebLogic 버전에 대한 T3 경유 비인증 네트워크 공격을 기록했습니다. 모든 사용이 원격으로 도달 가능하다는 뜻은 아닙니다.
네이티브 직렬화를 제거할 수 없다면
- ✓명시적 스키마가 있는 JSON 또는 Protocol Buffers를 우선하고 고정 DTO로 바꾼 뒤 필드와 권한을 검증합니다.
- ✓불가피하면
readObject()전에 컨텍스트별ObjectInputFilter를 설정하고 필요한 정확한 클래스만 허용합니다. - ✓정상 입력을 측정해 깊이, 참조, 배열, 스트림 바이트를 제한합니다. 허용 목록만으로 자원 고갈을 막을 수 없습니다.
- ✓신뢰할 수 없는 JSON에 광범위한 다형성 타입 지정을 켜지 않습니다. 임의 subtype 메타데이터가 객체 생성을 되살릴 수 있습니다.
- ✓Java와 종속성을 업데이트하고 불필요한 라이브러리를 제거하며 레거시 스트림은 최소 권한과 자원 제한으로 처리합니다.
자주 묻는 질문
ObjectInputFilter가 readObject()를 안전하게 만드나요?
좁은 허용 목록과 제한으로 위험을 줄이지만 만능 정화기는 아닙니다. 허용 클래스와 동작, 필터 활성화, 앱 검증과 권한 확인이 여전히 중요합니다. 가능하면 사용자 제어 데이터에 네이티브 직렬화를 사용하지 마세요.