Huny's Dev Blog
huny.dev

Apache Airflow 3.4.0 보안 업데이트(CVE-2026-68982) 해부: CeleryExecutor의 ExecuteCallback 무인증 RCE 원리와 브로커·워커 점검하기

11월 9일 공개된 Apache Airflow CeleryExecutor 무인증 원격 코드 실행 취약점(CVE-2026-68982)의 ExecuteCallback 토큰 검증 누락 원리와 3.4.0 패치를 정리한다. DAG·UI 흔적 없이 동작하는 공격 구조와 5건의 동시 패치 취약점 점검 절차를 살펴본다.

Hun Jang
Hun Jang Nov 10, 2026

Celery 브로커의 ExecuteTask와 달리 토큰 검증이 빠져 있던 ExecuteCallback 워크로드 경로를 Airflow 3.4.0의 Execution API 일회용 토큰 검증 게이트로 차단하는 개념 일러스트다. 실제 콘솔 화면이 아니다.

2026년 11월 9일 Apache Airflow 보안팀이 CeleryExecutor 환경에서 브로커(Redis, RabbitMQ)에 접근할 수 있는 공격자가 Airflow 계정이나 유효한 토큰 없이 모든 워커(Worker) 노드에서 임의의 Python 함수를 실행할 수 있는 무인증 원격 코드 실행(RCE) 취약점인 CVE-2026-68982(CWE-306)와 5건의 연관 역직렬화·캐시 보안 취약점을 한꺼번에 공개했다. 이 문제들은 11월 6일 배포된 Apache Airflow 3.4.0에서 수정되었으며, 3.3.1·3.3.2를 포함한 3.4.0 미만의 모든 버전이 영향을 받는다. CVE-2026-68982 공식 레코드, NVD 상세 정보, 발견자 Reflectiz(Or Sahar) 기술 분석, Rapid7 취약점 DB

결론부터 말하면 “우리 클러스터는 Deadline Alerts 기능을 쓰지 않고 등록된 DAG도 없다”거나 “Airflow 웹 UI·API에서 이상한 DagRun이 보이지 않는다”는 이유로 안심해서는 안 된다. 취약한 ExecuteCallback 핸들러는 Celery 프로바이더가 로드되는 순간 모든 CeleryExecutor 워커에 자동 등록되며, 브로커로 직접 주입된 위조 콜백 메시지는 스케줄러와 메타데이터 DB를 아예 거치지 않아 Airflow UI나 REST API에 어떠한 DagRun·TaskInstance 흔적도 남기지 않는다. 또한 3.4.0 패치는 워커가 Execution API 서버를 통해 일회용 토큰을 검증하도록 구조를 바꾼 것이므로, 워커와 Execution API 서버 양쪽을 모두 Airflow 3.4.0 이상으로 동시에 업그레이드해야 효력이 발생한다.

이 글은 NVD CVE-2026-68982 공지와 Reflectiz의 원본 분석 보고서, 2026년 11월 9일 동시 공개된 Airflow 보안 공지 요약을 교차 검증해 정리한 대응 가이드다. 실제 상용 클러스터에 위조 브로커 메시지를 주입하는 실험은 수행하지 않았으며, 로컬 Python 검증 코드는 ExecuteTask와 ExecuteCallback의 토큰 검증 분기 차이 및 일회용 토큰 상환(Redemption) 로직만 시뮬레이션한다.

1. 세 개의 문 중 하나만 열려 있었다: ExecuteTask와 ExecuteCallback의 검증 비대칭

Airflow 3.x 아키텍처에서 워커가 코드를 실행하도록 지시받는 경로는 크게 세 가지다. 웹 UI·REST API와 일반 태스크(ExecuteTask)는 서명된 JWT 토큰을 검증했지만, 동기식 Deadline Alert 콜백을 처리하기 위해 같은 Celery 태스크(execute_workload) 안에 추가된 ExecuteCallback 분기만 토큰 검증이 누락되어 있었다.

비교 항목
경로 1: 웹 UI 및 REST API
경로 2: 브로커 ExecuteTask 워크로드
경로 3: 브로커 ExecuteCallback 워크로드 (3.4.0 미만 취약)
전달 채널 및 진입점
HTTP 요청 (/api/v2/...)
Celery 브로커 execute_workload 태스크 (type: "ExecuteTask")
Celery 브로커 execute_workload 태스크 (type: "ExecuteCallback")
토큰·자격증명 검증 여부
검증함. 유효한 사용자·서비스 인증 없으면 401/403 거부
검증함. supervise_task()가 Execution API를 통해 서명된 워크로드 토큰을 검증한 뒤 실행
검증 누락(CWE-306). 페이로드에 token 필드가 존재하지만 빈 문자열("")이나 임의 값을 넣어도 확인하지 않고 즉시 실행
실행 메커니즘
스케줄러를 통해 DAG 실행 예약
등록된 DAG 파일 내 정의된 태스크 실행
공격자가 지정한 callback.data.path를 import_module()과 getattr()로 동적 로드해 kwargs와 함께 즉시 호출 (예: os.system)
사전 조건 및 UI 감사 흔적
유효한 계정 및 DAG 필요 / UI·API에 기록 남음
유효한 DagRun 및 토큰 필요 / UI·API에 기록 남음
DAG 0개·Deadline Alert 미설정 상태에서도 동작함. DagRun이나 TaskInstance를 만들지 않아 Airflow UI·API에 흔적이 전혀 남지 않음

특히 Airflow 3.3.0에서는 콜백 실행이 CallbackSubprocess라는 포크된 자식 프로세스로 분리되면서 내부적으로 토큰을 담은 httpx.Client 객체를 생성하도록 코드가 바뀌었지만, 정작 콜백 함수를 호출하기 전에 서버로 토큰 검증 요청을 보내는 코드는 들어가지 않아 3.2.1과 동일하게 무인증 실행이 가능했다.

Airflow 3.4.0의 수정 방식(apache/airflow#71192): 워커가 ExecuteCallback을 실행하기 전에 반드시 Execution API 서버에 콜백 실행 권한을 청구(Claim)하고 일회용(Single-use) 워크로드 토큰을 검증하도록 강제했다.

2. Airflow 3.4.0에서 함께 수정된 5건의 연관 취약점 경계

11월 9일 보안 공지에서는 브로커 콜백 RCE(CVE-2026-68982) 외에도 스케줄러·Execution API의 역직렬화 및 멀티팀 시크릿 캐시 취약점 5건이 동시에 공개되었다. 모두 Airflow 3.4.0으로 업그레이드해야 해결된다.

CVE 식별자
취약 컴포넌트 및 위험도
핵심 원인 및 공격 경로
Airflow 3.4.0의 수정 내용 및 운영 조치
CVE-2026-68982
CeleryExecutor 워커
(Important / Reflectiz 평가 CVSS 9.8)
브로커의 ExecuteCallback 워크로드 토큰 미검증으로 임의 Python 모듈·함수 무인증 원격 실행
Execution API를 통한 일회용 토큰 검증 의무화 (API 서버와 모든 워커 동시 3.4.0 업그레이드 필수)
CVE-2026-82337
스케줄러 및 API 서버
(High — CVE-2026-45360 불완전 패치 보완)
직렬화된 DAG의 DeadlineAlert 복원 시 이전 패치가 reference 필드만 막고 callback·interval 필드의 일반 역직렬화를 허용해 허용 목록 내 임의 클래스 인스턴스화 가능
DeadlineAlert의 모든 필드에 플러그인 등록 및 역직렬화 게이트 일괄 적용 (3.4.0 업그레이드)
CVE-2026-86829
스케줄러 의존성 평가기
(High)
스케줄러가 태스크 의존성을 평가할 때 태스크가 기록한 XCom 값을 전체 역직렬화하여, DAG 작성자 권한이 배포 관리자(Deployment Manager) 영역인 스케줄러 프로세스 실행으로 확장됨
의존성 평가 시 XCom 값을 원시 타입(Primitive values)으로만 제한 (3.4.0 업그레이드)
CVE-2026-111421
Execution API set_xcom
(High)
Execution API의 set_xcom 경로에서 예약 키(Reserved-key) 검사가 누락되어 태스크가 작성한 XCom이 API 서버에서 airflow.* 내부 클래스를 인스턴스화할 수 있음
set_xcom 경로에 예약 키 검증 강제 적용 (3.4.0 업그레이드)
CVE-2026-96285
스케줄러 next_kwargs
(Moderate/High)
스케줄러에서 태스크 재개(Resume) 데이터인 next_kwargs를 dict 타입 검사 이전에 역직렬화하여 임의 생성자 호출 가능
역직렬화 전 타입 및 순서 검증 수정 (3.4.0 업그레이드)
CVE-2026-76185
Task SDK SecretCache
(Moderate/High)
multi_team과 use_cache를 동시에 켰을 때 팀 캐시 키가 단사(Injective) 구조를 갖지 않아 팀 간 시크릿 충돌·노출 발생
3.4.0에서 캐시 키 구분자 수정 (패치 전에는 멀티팀 환경에서 use_cache 비활성화)

3. 브로커 노출 점검 및 3.4.0 업그레이드·로그 감사 명령어

Reflectiz의 Shodan 조사에 따르면 외부에서 접근 가능한 Airflow/Celery용 Redis 브로커 211개 중 198개(약 94%)가 비밀번호 인증(AUTH) 없이 열려 있었다. 또한 Airflow 공식 Docker Compose 빠른 시작 예제도 기본적으로 Redis 비밀번호를 설정하지 않으므로 내부망이나 컨테이너 네트워크에 도달한 공격자에게 그대로 노출된다.

즉시 수행해야 할 버전 확인, 브로커 인증 점검, 워커 프로세스 로그 감사 명령어는 다음과 같다.

4. 로컬 Python으로 검증하는 ExecuteCallback 토큰 우회와 3.4.0 방어 로직

왜 3.4.0 미만 워커에서는 빈 토큰("token": "")을 가진 ExecuteTask는 거부되면서 동일한 빈 토큰을 가진 ExecuteCallback은 그대로 실행되었는지, 그리고 3.4.0의 Execution API 일회용 토큰 상환이 이를 어떻게 차단하는지 로컬 Python 코드로 검증했다.

직접 실행해 확인한 범위

로컬 Python 환경에서 세 가지 시나리오를 실행해 검증했다.

  1. 3.4.0 미만 워커에 빈 토큰 주입: {"type": "ExecuteTask", "token": ""}는 401_invalid_task_token으로 거부되지만, 동일한 빈 토큰을 가진 {"type": "ExecuteCallback", "token": "", ...}는 executed: True 및 ui_audit_trail: False로 통과한다.
  1. 3.4.0 패치 워커에 위조 콜백 주입: patched_3_4_worker_dispatch()는 모듈 임포트 이전에 토큰 상환 단계에서 즉시 401_unauthenticated_workload로 차단한다.
  1. 일회용 토큰 재사용(Replay) 차단: 정상 발급된 토큰(valid_jwt_02)은 첫 번째 ExecuteCallback 실행 시 정상 통과한 뒤 즉시 소진되어, 동일한 메시지를 브로커에서 다시 재전송하면 두 번째 호출은 거부된다.

5. 실무 보안 점검 체크리스트

  • Execution API 서버와 모든 Celery 워커 동시 3.4.0 업그레이드: 한쪽만 업그레이드하면 콜백 토큰 검증 계약이 맞지 않거나 구버전 워커가 그대로 위조 메시지를 실행하므로 클러스터 전체를 3.4.0 이상으로 함께 올린다.
  • 브로커 인증(requirepass / RabbitMQ 계정) 및 네트워크 격리 즉시 적용: 패치 여부와 무관하게 Redis 포트(6379)와 RabbitMQ 포트(5672)를 외부 인터넷 및 비신뢰 서브넷에서 차단하고 브로커 자체 인증을 필수로 건다.
  • 침해 의심 시 워커의 Fernet 키 및 클라우드 자격증명 교체: 워커에서 임의 코드가 실행되면 워커 환경 변수(AIRFLOW__*)에 들어 있는 메타데이터 DB 비밀번호와 Fernet 암호화 키, AWS/GCP 자격증명이 모두 노출될 수 있으므로, 브로커가 무인증으로 노출되어 있었다면 패치 후 시크릿과 Fernet 키를 반드시 로테이션한다.

참고 자료

확인 기준일: November 10, 2026

English version: Apache Airflow 3.4.0 Security Update (CVE-2026-68982): How ExecuteCallback Bypasses Worker Auth and What to PatchApache Airflow 3.4.0 Security Update (CVE-2026-68982): How ExecuteCallback Bypasses Worker Auth and What to Patch

추천 글