🇰🇷 한글 설명
Kafka의 여러 역직렬화 경로가 입력 데이터에서 읽은 크기/개수 필드를 실제 가용 바이트 검사 없이 배열, 컬렉션, 바이트 버퍼 할당에 직접 사용합니다. 조작된 작은 입력으로 수 GB 규모의 메모리 할당을 유도할 수 있습니다. 영향 범위는 Kafka Streams(ProcessorRecordContext, ChangedDeserializer, CombinedKeySchema, ProcessorMetadata, AssignmentInfo)와 클라이언트 라이브러리의 ListDeserializer입니다.
💡 쉬운 설명
공격자가 아주 작은 데이터에 매우 큰 크기 값을 적어 넣으면, Kafka 소비자가 그만큼의 메모리를 잡으려다 메모리 부족 오류로 멈출 수 있습니다. 브로커나 클러스터 전체에는 영향을 주지 않습니다.
🇺🇸 원문 (English)
Several Kafka deserialization paths read a size or count field from input data and use it directly to allocate an array, collection, or byte buffer, with no check against the bytes actually available. A small crafted input can therefore declare a very large size and force a multi-gigabyte allocation. The affected paths are, in Kafka Streams, ProcessorRecordContext (header count), ChangedDeserializer (varint value length), CombinedKeySchema (foreign-key length, which could also produce a negative size), ProcessorMetadata (key length), and AssignmentInfo group-assignment decoding; and, in the clients library, ListDeserializer (used by ListSerde).
Impact:
An attacker can trigger the oversized allocation and raise an OutOfMemoryError that crashes the affected consumer or Kafka Streams thread; the broker and the rest of the cluster are unaffected. The reachable surface depends on the path: writing a crafted record to a Streams application's internal changelog or repartition topics, or committing crafted offset metadata to its consumer group (Streams internal paths); writing a crafted record to any topic that a consumer reads with ListSerde (ListDeserializer); or, as a member of a Streams consumer group, returning crafted assignment data when elected leader (AssignmentInfo). Because a crafted record remains in its topic, the error can recur on restart. The record size limit (max.message.bytes) does not help, because the allocation is driven by a size field rather than by the input's length.
Mitigation:
Upgrade to Apache Kafka 4.2.2, 4.3.2, or 4.4.0. Where authorization is enabled, restrict write access to each application's internal topics and consumer group to its own principal, and restrict who can produce to topics that are consumed with ListSerde.
Resolution:
From Apache Kafka 4.2.2, 4.3.2, and 4.4.0: these deserialization paths validate the declared size against the remaining input before allocating and reject input that fails the check.
📍 영향받는 시스템
Apache Kafka 클라이언트 및 Kafka Streams (수정 전 버전, 4.2.2 / 4.3.2 / 4.4.0 미만)
⚔️ 공격 벡터
조작된 레코드를 Streams 내부 changelog/repartition 토픽이나 ListSerde로 읽는 토픽에 기록하거나, 악의적 할당 데이터를 반환하는 방식으로 메모리 부족 오류를 유발
🛡️ 대응 방법
Apache Kafka 4.2.2, 4.3.2 또는 4.4.0 이상으로 업그레이드하고, 인가가 활성화된 경우 내부 토픽 및 컨슈머 그룹 쓰기 권한을 해당 애플리케이션 주체로 제한
🔧 검증 코드
출력된 버전이 4.2.2, 4.3.2, 4.4.0 중 하나 이상이면 패치된 것이며, 그보다 낮은 4.2.x/4.3.x 또는 4.4.0 미만이면 취약합니다. 명령이 실패하면 Kafka 설치 경로를 직접 확인해야 합니다.
kafka-topics.sh --version 2>/dev/null || (ls /opt/kafka*/libs/kafka-clients-*.jar 2>/dev/null | head -1)