Apache DataSketches Java의 일부 역직렬화 처리는 직렬화된 입력이 스스로 선언한 크기와 개수를 확인하기 전에 메모리를 확보한다. 그래서 아주 작은 조작 입력이 과도한 할당을 끌어내 OutOfMemoryError를 만들 수 있고, 문자열 기반 FrequentLongsSketch.getInstance(String) 경로에서는 역직렬화나 후속 업데이트가 끝나지 않을 수 있다. 다만 CVE 레코드는 영향 대상을 한 문장으로 좁혀 둔다. 이 조건이 점검 범위를 정하는 출발점이다.
개요

Apache DataSketches Java의 역직렬화기가 직렬화된 입력의 크기·개수를 충분히 검증하지 않는 문제가 GHSA-jghc-rj2j-x37x로 공개됐다.
- 식별자:
CVE-2026-122096,GHSA-jghc-rj2j-x37x - 영향 버전: Apache DataSketches Java 9.0.0까지
- 수정 버전: 9.1.0
- 확인되는 증상: 과도한 메모리 할당으로 인한
OutOfMemoryError, 끝나지 않는 역직렬화 또는 후속 업데이트
핵심은 라이브러리를 의존성에 포함했는지 여부가 아니다. CVE 레코드는 영향 대상을 Only applications that deserialize sketches from untrusted sources are affected. 한 문장으로 명시한다. 조립된 스케치 이미지를 되살리는 경로가 외부 입력에 열려 있는지가 판단의 중심이고, 버전 확인은 그다음 단계로 보는 편이 정확하다.
영향 범위
GHSA 권고는 영향을 Apache DataSketches Java: through 9.0.0으로 적고, 문제를 고친 9.1.0으로 업그레이드할 것을 권한다.
버전 목록만 확인해서는 노출 범위가 정해지지 않는다. 개요에서 인용한 적용 조건을 함께 놓으면, 실질적 영향 범위는 9.0.0 이하 + 신뢰할 수 없는 스케치 역직렬화 경로로 좁혀진다. 같은 9.0.0을 쓰더라도 해당 경로가 없으면 노출 조건에 들어가지 않고, 경로가 있다면 확인 순서가 버전을 앞선다.
또 다른 제약은 배포 환경이다. 9.1.0 릴리스는 9.0.0과 소스·바이너리 호환을 표방하는 마이너 릴리스이지만, 9.0.0과 마찬가지로 Java 25를 요구한다. 따라서 노출 범위를 확인하는 일과 별도로, 업그레이드가 실제로 가능한지는 Java 런타임 조건이 함께 결정한다.
기술적 분석
할당보다 늦게 도착하는 검증
CVE 레코드는 여러 역직렬화기가 직렬화된 입력이 선언한 크기와 개수를 신뢰했다고 설명한다. 그 결과 작은 조작 입력으로도 애플리케이션이 과도한 메모리를 할당해 OutOfMemoryError에 이를 수 있다. 입력이 스스로 밝힌 수치를 신뢰의 근거로 쓰는 구조에서는, 문제를 일으키는 데 필요한 입력 크기 자체도 작아진다.
문자열 직렬화 형태에서는 같은 결함이 PR #783에 더 구체적으로 적혀 있다. UTF-8과 UTF-16 문자열 SerDes가 직렬화된 개수와 길이 접두사에서 배열을 할당하면서, 그 바이트가 실제로 입력 구간에 담겨 있는지는 나중에야 확인했다는 것이다. 그래서 기대했던 경계 예외 대신 NegativeArraySizeException이나 OutOfMemoryError가 나올 수 있다. 수정은 출력 배열을 할당하기 전에 최소 접두사 공간을 확인하고, 각 문자열의 바이트 버퍼를 할당하기 전에 페이로드를 검증하는 방향이다.
정상적으로는 경계 예외가 나와야 할 입력 경로에서 다른 종류의 예외가 반복해 나타난다면, 검증이 할당보다 늦게 일어나는 구조적 원인을 의심해 볼 수 있다. 이는 어떤 입력 경로를 먼저 되짚어 볼지에 대한 조건부 시사이고, 현상 자체가 악용을 증명하는 것은 아니다.
빈 슬롯을 못 찾아 도는 탐색 루프
메모리 밖의 문제도 있다. PR #777에 따르면 FrequentLongsSketch.getInstance(String)은 문자열의 길이 토큰과 numActive 토큰으로 해시 맵을 만들면서, 두 값을 실제 맵에 대해 검증하지 않는다. ReversePurgeLongHashMap의 탐색 루프인 adjustOrPutValue와 hashProbe는 빈 슬롯에서만 멈추고, 유일한 방어가 assert뿐이다. 모든 슬롯이 채워지면 새 키를 찾는 탐색은 영원히 돈다.
PR에 적힌 재현 예는 증상이 나타나는 시점이 두 가지로 나뉜다. 어떤 입력은 역직렬화 호출 자체에서 돌아오지 않고, 어떤 입력은 역직렬화를 통과한 뒤 세 번째 별개 갱신에서 멈친다. 후자는 맵 길이를 2슬롯으로 주장하는 이미지에서 curMapCap이 8슬롯 최소값 기준으로 계산되어 실제로는 2슬롯뿐인 맵과 어긋나기 때문에 생긴다. 두 재현 값과 그 출처는 아래 PoC 분석에서 한 번만 정리한다.
후속 갱신에서 멈추는 쪽이 더 까다롭다. 역직렬화가 예외 없이 끝났다는 사실을 안전의 증거로 쓰는 검증은 이 결함을 잡지 못한다. 같은 이미지가 처음 몇 번의 갱신까지는 정상처럼 지나간 뒤 막힐 수 있어서, 증상의 시점이 원인 시점과 어긋난다.
공개 PoC·익스플로잇 분석
출처: 이 취약점에서 공개된 재현 입력은 벤더의 수정 작업 자체에서 확인된다. PR #777는 FrequentLongsSketch.getInstance(String)의 undersized map 문제를 다루면서 재현 값으로 "1,10,3,0,3,0,3,2,1,1,2,1,3,1"과 "1,10,3,5,0,0,0,2"를 적어 두고, 앞의 값은 호출이 돌아오지 않고 뒤의 값은 역직렬화는 통과한 뒤 세 번째 별개 갱신에서 멈친다고 서술한다. 이 재현 값들은 수정 PR에 공개되어 있는 형태로 확인된다. CVE 레코드도 A crafted string passed to FrequentLongsSketch.getInstance(String) could also make deserialization, or a later update, loop indefinitely.라고 같은 현상을 기록한다.
전제조건: 재현 값이 의미를 가지려면 문자열 형태의 스케치 이미지를 FrequentLongsSketch.getInstance(String)에 넘기는 호출이 실제로 존재해야 하고, 그 호출이 신뢰할 수 없는 출처의 문자열을 처리하는 경우라야 레코드가 말한 영향 조건에 해당한다. PR의 설명대로 탐색이 끝나지 않는 상황은 맵의 모든 슬롯이 채워진 뒤 새 키를 찾게 될 때 나타나므로, 역직렬화 시점에 아무 증상 없이 통과한 이미지도 후속 갱신에서 같은 조건에 들어갈 수 있다.
입증 범위: 자료는 재현 입력에서 탐색이 끝나지 않는 현상까지를 뒷받침한다. 메모리 고갈 축은 CVE 레코드의 A small crafted input could make an application allocate an excessive amount of memory, leading to an OutOfMemoryError. 서술과 PR #783의 설명으로 확인되지만, 이 글이 사용한 자료에는 메모리 고갈까지 실제로 보이는 구체적인 재현 값은 담겨 있지 않다. 실제 환경에서 이 취약점이 악용된 사례는 확인되지 않았고, 독립적인 기술 검증도 확인되지 않았다. 확인되지 않았다는 사실이 악용의 부재를 뜻하지는 않는다.
운영상 의미: 재현 입력이 수정 PR에 명시돼 있다는 사실은, 영향 조건을 갖춘 애플리케이션에서 호출이 돌아오지 않는 상황을 매우 작은 입력으로도 만들 수 있음을 조건부적으로 시사한다. 따라서 영향 경로에서 나타나는 OutOfMemoryError와 끝나지 않는 역직렬화·후속 업데이트는 악용을 확정하는 증거가 아니라 점검을 시작할 단서에 가깝다. 재현 값의 존재를 곧바로 실전 악용 지표로 읽는 쪽도, 악용 사례가 확인되지 않았다는 사실을 안전의 근거로 쓰는 쪽도 자료의 범위를 벗어난다.
대응 방안
지금 확인할 것
- 사용 중인 Apache DataSketches Java 버전이 9.0.0 이하인지 확인한다.
- 스케치 역직렬화 입력이 어디에서 오는지 신뢰 경계를 정리하고, 영향 버전에서 신뢰할 수 없는 출처의 스케치를 역직렬화하는 경로가 있는지 먼저 파악한다.
- 해당 경로에서
OutOfMemoryError와 끝나지 않는 역직렬화·후속 업데이트가 나타나고 있는지 과거 로그와 실행 동작을 기준으로 살펴본다. 나타난 현상은 단서이지 결론이 아니다.
업그레이드 전의 제한 검토
업그레이드 전까지는 업무 영향을 고려해 신뢰할 수 없는 스케치의 역직렬화 경로를 제한하는 방안을 검토할 수 있다. 다만 이 제한은 검증된 완화책이 아니라 입력 신뢰 경로를 좁혀 노출 조건 자체를 줄이는 성격의 선택으로 보고, 업그레이드로 마무리하는 편이 바람직하다.
9.1.0으로의 업그레이드
권고되는 항구 조치는 9.1.0으로 업그레이드하는 것이다. 릴리스 노트는 9.0.0과 소스 및 바이너리 호환을 밝히면서도 Java 25를 요구한다고 적는다. 같은 릴리스는 모든 스케치 계열의 역직렬화를 훨씬 엄격하게 만들고, 몇몇 계열의 직렬화 이미지를 C++와 바이트 단위로 일치시킨다고도 설명한다. 저장해 둔 이미지를 다시 읽거나 구현 간에 이미지를 주고받는 용도라면 업그레이드 후 동작 확인이 필요하다. 호환성을 밝히는 문구 자체가 기존 애플리케이션의 변경 영향을 보증하지는 않기 때문이다.
수정 버전은 메모리를 할당하거나 데이터를 읽기 전에 역직렬화 입력을 검증하고, 잘못되었거나 잘린 입력을 SketchesArgumentException을 비롯한 Sketches*Exception으로 거부한다. 같은 릴리스 노트가 All deserializers now validate their input before allocating memory or reading data.라고 밝히는 지점이다. 업그레이드 후에는 애플리케이션의 예외 처리가 함께 점검 대상이 된다. 예외를 로그 없이 삼키던 경로가 남아 있으면, 거부되어야 할 입력이 조용한 실패로 바뀔 수 있다.
남은 공백
자료에는 환경별 탐지 규칙도, 업그레이드가 어려운 환경을 위한 검증된 대체 완화책도 제시되어 있지 않다. 실제 악용 사례와 독립적인 기술 검증 역시 확인되지 않았다. 이 글이 제안하는 우선순위는 경로 확인 → 조건부 제한 → 호환성 검증 후 업그레이드라는 순서이며, 이는 확인된 사실에서 끌어낸 해석일 뿐 자료 자체가 보증한 절차는 아니다.
참고자료
- Apache DataSketches Java: Uncontrolled resource consumption when deserializing crafted sketch images
- CVE-2026-122096 · GHSA-jghc-rj2j-x37x
- Apache Release DataSketches-Java 9.1.0
- Reject undersized map in FrequentLongsSketch.getInstance(String) · Pull Request #777
- Validate string SerDe bounds before allocation · Pull Request #783
함께 읽으면 좋은 글
- CVE-2026-86343: 시놀로지 DSM SNMP API의 CRLF 취약점, 영향 버전과 대응 범위
- CVE-2026-0323: Checkov by Prisma Cloud 외부 Terraform 모듈 SSRF 취약점 점검
- CVE-2026-120006: .NET Aspire Dashboard 인증 쿠키 노출과 개발자 권한 코드 실행
본 콘텐츠는 AI 기술로 작성된 분석 리포트를 포함하고 있습니다. 내용 중 사실과 다르거나 보완이 필요한 정보를 발견하셨으면 댓글을 통해 의견을 부탁드립니다. 여러분의 피드백은 더 정확한 보안 정보 공유에 큰 도움이 됩니다.
댓글 (0)
댓글을 작성하려면 로그인이 필요합니다.
로그인아직 댓글이 없습니다.
첫 번째 댓글을 작성해보세요!