LiteLLM Proxy의
/config/update
에서 인증상의 미비점이 있어 읽기 전용 계정으로부터 관리자 권한 탈취까지 도달할 수 있었습니다 (CVE-2026-35029, 수정 버전 1.83.0, CVSS v4.0 기준 8.7점) (1). 본고는 절차 중심의 실전편입니다.
자신의 환경에 설치된 LiteLLM이 수정 버전인지, 마스터 키가 기본값으로 남아있지 않은지를 점검하는 작은 스크립트를 만듭니다.
스크립트 동작은 버전과 샘플 YAML을 통해 확인했습니다 (Python 3.13, 2026-11-04). 취약한 환경에서의 공격 재현은 수행하지 않았습니다.
배경 및 공격 흐름은 같은 날의 Zenn 기사에 작성했습니다. 본고는 Tips 위주로 구성하여 중복을 피했습니다.
다음 3가지에 답할 수 없다면, 먼저 확인해 주십시오.
- 운영 중인 LiteLLM 버전이 1.83.0 이상인가요? (GHSA에서는 1.82.6까지를 영향 범위로 나열하고 있습니다 (1))
- 마스터 키가 설정되어 있으며,
sk-1234
와 같은 예시 값은 아닌가요? (Zenity에 따르면, 인증은 마스터 키가 설정된 경우에만 강제되며, 관측된 공격은 기본 키나 미설정 환경을 노렸습니다 (2))
- 관리 화면과
/config/update,
/get_image
이 인터넷으로부터 접근 가능한 상태는 아닌가요?
1번과 2번은 스크립트로 확인할 수 있습니다. 3번은 네트워크 측면의 확인이 필요합니다.
설치된 LiteLLM 버전을 읽어 수정 버전(1.83.0)과 비교합니다. 설치되지 않은 환경(별도의 서버 설정을 점검하는 경우 등)에서는 버전을 인수로 전달할 수 있습니다. 설정 파일을 전달하면, master_key의 값도 확인할 수 있습니다.
# ll_check.py (Python 3.13, 표준 라이브러리만 사용)
import re, sys, os
from importlib import metadata
...
사용 방법은 다음과 같습니다.
# 설치된 환경에서
python3 ll_check.py
# 버전을 직접 전달하고, 설정 파일도 점검합니다
...
버전 판정은 경계 전후를 확인했습니다 (2026-11-04, 작성자 환경).
$ for v in 1.74.0 1.82.6 1.83.0 1.95.1; do python3 ll_check.py $v; done
litellm 1.74.0: VULNERABLE (수정 버전은 1.83.0 이상)
litellm 1.82.6: VULNERABLE (수정 버전은 1.83.0 이상)
...
설정 파일 점검은 다음 두 가지로 확인했습니다.
$ cat c1.yaml
general_settings:
master_key: sk-1234
...
환경 변수를 참조하는 경우에는, 참조되는 값까지는 확인하지 않습니다. 환경 변수 내용이 sk-1234가 아닌지는 별도로 확인해야 합니다.
- 1.83.0 이상으로 업데이트합니다. GHSA에 따르면, 설정 레벨의 회피책은 없으며, 업데이트가 유일한 근본 대책입니다 (1).
- 업데이트 전에, 취약한 버전을 공개했던 기간을 확인합니다.
- 그 기간 동안 인터넷으로부터 접근 가능했다면, 침해를 의심하고 다음 4.3으로 진행합니다.
예시 값 그대로라면, 공격자가 해당 키로 관리 API를 호출할 수 있습니다. 다음 절차에 따라 변경합니다.
- 충분히 긴 무작위 값을 생성합니다.
- 환경 변수(또는 비밀 관리 서비스)에서 읽어옵니다. 설정 파일에 평문으로 작성하지 않습니다.
- 변경 후, 이전 키로는 연결이 거부되는지 확인합니다.
python3 -c "import secrets; print('sk-' + secrets.token_urlsafe(32))"
위 명령어는 Python의 표준 라이브러리로, 추측하기 어려운 값을 생성하는 예시입니다.
Zenity의 기술 내용에 따르면, 공격 연쇄를 통해 데이터베이스 연결 문자열, 프로바이더 API 키, Langfuse의 키 등이 읽힐 수 있습니다 (2). 다음 순서로 진행합니다.
⚠️ [IMG:N]
| 순서 | 조치 사항 | 보충 설명 |
|---|
| 1 | 외부 노출 차단 | 관리 화면과 /config/update, /get_image 접근을 막습니다. |
| 2 | 로그 확인 | /config/update 호출, UI_LOGO_PATH 변경 여부, 의심스러운 패스스루 엔드포인트를 점검합니다. |
| 3 | 비밀 정보 로테이션 (교체) | DB 연결 정보, 각 프로바이더의 API 키, Langfuse 키, 마스터 키를 교체합니다. |
| 4 | 프로바이더 측 사용량 모니터링 | 갑작스러운 증가세는 키가 부정하게 사용되고 있다는 신호일 수 있습니다. |
| 5 | 관리자 계정 확인 | UI_USERNAME과 UI_PASSWORD가 임의로 수정되지 않았는지 확인합니다. |
버전 정보 확보의 어려움. pip show 명령어로 버전이 검색되지 않는 환경(예: 컨테이너 외부에서 실행하는 경우)에서는 인자(argument)를 통해 버전을 전달해야 합니다. 또한, 컨테이너 이미지 태그도 확인해야 합니다.
이미지 태그가 고정되어 있지 않으면 재시작할 때마다 버전이 달라질 수 있으므로, 점검 시점의 버전을 기록해 두어야 합니다. latest 태그는 위험합니다.
환경 변수 참조. os.environ/... 형식은 스크립트상으로는 내부 내용을 확인하지 않습니다. 실제 값은 별도로 반드시 확인해야 합니다.
정보 출처가 혼재됨. 제3자 사이트에는 다른 버전(1.95.0)이나 CVSS 점수(8.1)로 작성된 권고 사항도 있었습니다 (※3). 필자는 1차 정보로 확인하지 못했기 때문에, 본 글에서는 CVE-2026-35029의 1.83.0을 기준으로 삼았습니다. 더 안전한 쪽으로 업데이트하는 것은 손해가 없습니다.
점검 스크립트는 판단 과정을 단순화해줍니다. 버전과 키라는 두 가지 항목은 몇 초 만에 기계적으로 파악할 수 있습니다. 하지만 이것만으로는 '안전하다'고 말할 수 없습니다. 네트워크 공개 범위나 과거 침해 여부는 사람이 직접 확인해야 합니다.
또한, 이 스크립트는 공격을 재현하지 않았습니다. 판단의 근거는 GHSA에 작성된 버전 범위에 국한됩니다. Zenity는 1.81.0에서는 403으로 거부되었다고 언급하여, 취약점 버전의 경계가 자료마다 다릅니다. 안전한 쪽으로 기울여서, 1.83.0 이전은 모두 대상(취약)으로 간주하는 것이 좋습니다.
LiteLLM의 CVE-2026-35029에 대비하여 버전과 마스터 키를 점검하는 작은 스크립트를 만들고, 경계값 및 샘플 설정을 통해 작동 여부를 확인했습니다. 취약한 환경에서의 공격 재현은 수행하지 않았습니다. 1.83.0 이상으로 업데이트, 마스터 키 검토, 관리 API의 공개 범위 제한, 그리고 침해가 의심되는 경우 키 로테이션. 이 네 가지 사항을 오늘 중으로 반드시 점검해야 합니다.
※본 기사에 기재된 내용은 필자 개인의 견해이며, 소속 회사나 조직의 입장 및 방침과는 전혀 관련이 없습니다.
【Tomcat-zhou】|AI/AX/AI 보안 전문가
AI 전략 통찰력, AI 구동 개발 방법론 설계와 현장에서 작동하는 시스템 구축을 하고 있습니다.
note에서 전략 통찰 / Zenn・Qiita에서 기술 및 방법론을 작성하고 있습니다.
AI 보안·AI 컨설팅·AI 에이전트 개발·AI 활용·AI 구동 개발 교육, AI 인재 육성 서비스를 통합적으로 제공합니다.
X: @ZY20240528
LinkedIn: Tomcat-zhou
Facebook: zhou yi
note: Tomcat-zhou
Zenn: Tomcat-zhou
- GHSA-53mr-6c8q-9789 / CVE-2026-35029 (OSV)
- A Read-Only Account is All it Takes to Own a LiteLLM Server (Zenity Labs)
- AI Changelog Week 44 (neomanex)
LiteLLM
AI
Python
보안
LLM