블로그 이미지
Cloud Engineer

클라우드 & 쿠버네티스 엔지니어의 기술 기록

쿠버네티스 기반 프라이빗 클라우드 구축·운영과 레거시 → 클라우드 전환 경험을 정리합니다. 직접 부딪힌 문제와 트러블슈팅 과정을 위주로 기록해요.

Kubernetes Private Cloud Legacy to Cloud
전체 방문자
오늘
어제

GitHub Activity

GitHub Stats Top Languages
GitHub Streak

Tech Stack

Container & Orchestration

OpenShift OpenShift Virtualization RKE2 Rancher Kubernetes Docker Helm

Middleware / WAS

JBoss Apache HTTPD Tomcat

Cloud

AWS Google Cloud

Auth / Identity

Keycloak Google OIDC OAuth2 Proxy

Automation / IaC

Ansible

카테고리 둘러보기

DevOps/Openshift Cloud Platform 2026. 9. 16. 09:36

CVE-2026-33814 정리 - OpenShift/Kubernetes를 강타한 HTTP/2 DoS 치명적 취약점

728x90

2026년 5월 공개되어 최근까지 OpenShift 전 컴포넌트에 패치가 이어지고 있는 고심각도 HTTP/2 DoS 취약점 CVE-2026-33814의 원인, 영향 범위, 실제 조치 사례, 탐지/조치 방법을 정리합니다.

취약점 개요

항목 내용
CVE ID CVE-2026-33814 (Go 취약점 DB: GO-2026-4918)
유형 HTTP/2 클라이언트 무한 루프로 인한 서비스 거부(DoS)
CVSS 3.1 7.5 (High) - 네트워크 공격 가능, 낮은 복잡도, 권한/상호작용 불필요, 가용성 영향만 존재
영향받는 패키지 golang.org/x/net/http2 (Go 표준 HTTP/2 트랜스포트 포함)
수정 버전 golang.org/x/net/http2 v0.53.0+, Go 1.25.10 / 1.26.3

원인 - 왜 무한 루프에 빠지는가

HTTP/2 스펙(RFC 7540 §6.5.2)은 SETTINGS_MAX_FRAME_SIZE 값이 최소 16,384바이트 이상이어야 한다고 규정합니다. 그런데 Go의 HTTP/2 트랜스포트 구현체는 이 하한선을 검증하지 않았습니다. 악의적이거나 오동작하는 서버가 SETTINGS 프레임 하나에 SETTINGS_MAX_FRAME_SIZE=0 값만 실어 보내면, 이후 클라이언트가 DATA 프레임을 쓰려고 할 때마다 실제로는 0바이트짜리 쓰기로 계산됩니다. 0바이트는 "진행"이 아니므로 쓰기 로직이 재시도를 반복하고, 이 재시도가 영원히 끝나지 않는 무한 루프로 이어집니다. 결과적으로 해당 트랜스포트를 처리하는 goroutine이 CPU를 100% 소모하며 스핀하다가 결국 프로세스가 다운되거나 응답 불능 상태가 됩니다.

1. 악성/오동작 서버 -> SETTINGS { SETTINGS_MAX_FRAME_SIZE: 0 } 전송
2. Go HTTP/2 클라이언트가 값 검증 없이 그대로 수락
3. 이후 DATA 프레임 전송 시도 -> 매번 0바이트 쓰기로 계산됨
4. "진행 없음" 판단 -> 즉시 재시도 -> 무한 루프
5. 해당 goroutine이 CPU/메모리를 무한 소모 -> 프로세스 행(hang) 또는 크래시

영향받는 Kubernetes/OpenShift 컴포넌트

Go로 작성되어 HTTP/2 클라이언트로 동작하는 모든 바이너리가 대상입니다. 즉 "서버를 공격"하는 취약점이 아니라, "이 컴포넌트들이 연결하는 상대방이 악의적일 때 클라이언트 쪽이 멈추는" 구조라는 점이 중요합니다.

컴포넌트 취약 경로
kube-apiserver 어드미션 웹훅, 확장 API 서버, kubelet 엔드포인트 호출 시 HTTP/2 클라이언트로 동작
kubelet apiserver에 연결하는 클라이언트
kube-controller-manager / kube-scheduler apiserver에 연결하는 클라이언트
Cluster API provider 컨트롤러 워크로드 클러스터 apiserver에 연결
kubectl, client-go 기반 애플리케이션 대상 apiserver에 연결하는 모든 클라이언트

실제 OpenShift 조치 사례

Red Hat은 이 CVE에 대해 release-4.15부터 release-4.20까지 여러 브랜치에 걸쳐 병렬로 패치를 진행했습니다. 대표적으로 다음과 같은 OCPBUGS 트래킹 하에 golang.org/x/net을 Red Hat이 자체 유지보수하는 openshift-sustaining/net 포크(보안 패치가 백포트된 버전)로 교체하는 방식으로 수정됐습니다.

트래킹 대상 컴포넌트 / 브랜치
OCPBUGS-103139 cloud-provider-aws, release-4.18 → openshift-sustaining/net v0.35.0-sec.4로 교체
OCPBUGS-102899 cloud-provider-aws, release-4.16
OCPBUGS-102704 cloud-provider-aws, release-4.15
OCPBUGS-103778 azure-service-operator → sustaining fork v0.50.0-sec.4로 교체
OCPBUGS-103964 oc CLI, release-4.20

탐지 방법

클러스터에서 이미 실행 중인 컴포넌트 바이너리가 여전히 취약한 버전을 링크하고 있는지는 govulncheck로 직접 확인할 수 있습니다.

# 이미지에서 바이너리 추출
crane export registry.k8s.io/kube-apiserver:v1.34.4 - | tar -x ./usr/local/bin/kube-apiserver

# 바이너리 모드로 govulncheck 실행
govulncheck -mode=binary ./usr/local/bin/kube-apiserver

# 결과에 GO-2026-4918 이 보이면 취약한 HTTP/2 트랜스포트가 아직 링크되어 있는 것

조치 가이드

  • 참고: OpenShift를 사용 중이라면 자체 패치보다 Red Hat이 배포하는 z-stream(4.15.x, 4.16.x, 4.18.x 등) 업데이트를 통해 반영하는 것이 정석입니다. 위 OCPBUGS들이 머지된 이후 릴리스로 업그레이드하면 해결됩니다.
  • 참고: 직접 관리하는 Go 애플리케이션이나 client-go 기반 컨트롤러가 있다면 go.mod의 golang.org/x/net을 v0.53.0 이상으로, Go 툴체인은 1.25.10 / 1.26.3 이상으로 올려야 합니다.
  • 주의: 이 취약점은 "서버가 클라이언트를 공격"하는 방향이므로, 웹훅 서버·확장 API 서버·써드파티 이미지 레지스트리 등 클러스터의 각 컴포넌트가 아웃바운드로 연결하는 모든 상대방을 신뢰할 수 있는지 함께 점검해야 실질적인 위험이 줄어듭니다.
  • 주의: CVSS 7.5(가용성 영향만)로 데이터 유출은 아니지만, apiserver나 kubelet이 멈추면 사실상 컨트롤 플레인 전체 장애로 번질 수 있어 우선순위를 높게 잡아야 하는 케이스입니다.
728x90