2026. 10. 27. 11:46ㆍ프로그래밍/기타

Tailscale 이슈에 이어서 이번 달은 Python 쪽도 보안 이슈가 한꺼번에 몰려 나왔습니다. Python 본체(CPython) 긴급 보안 릴리스, 많이 쓰는 라이브러리인 Brotli와 Pillow의 치명적 취약점, 그리고 LiteLLM 패키지 공급망 공격까지 있었습니다.
각각 무엇이 문제인지, 내 환경이 영향을 받는지 확인하는 방법, 그리고 조치 방법을 쉘 명령 위주로 정리했습니다.
3줄 요약
1. Python은 3.14.10 / 3.15.2(또는 3.13.18, 3.12.16, 3.11.18)로 올리고, 가상환경마다 pip, certifi를 업데이트하세요.
2. Brotli ≥ 1.2.1, brotlicffi ≥ 1.2.1.0, Pillow ≥ 13.0.0으로 올리고 lock 파일도 갱신하세요.
3. 10/21에 LiteLLM 1.107.0을 설치했다면 python/pip를 실행하지 말고 쉘에서 먼저 정리한 뒤 자격증명을 전부 교체하세요.

1. CPython 긴급 보안 릴리스 (eMudhra 인증서 사고 등)
인도 인증기관 eMudhra(emSign)의 중간 CA 인증서 8개 개인키가 유출되는 사고가 있었습니다. 이 키로 남의 도메인 인증서를 위조할 수 있기 때문에 브라우저뿐 아니라 Python처럼 자체 인증서 묶음을 쓰는 런타임도 대응이 필요했습니다.
- 10/21: Python 3.15.1, 3.14.9, 3.13.17 출시. 번들된 pip를 26.2.2(certifi 2026.10.19 포함)로 올렸습니다.
- 10/26: Python 3.15.2, 3.14.10, 3.13.18, 3.12.16, 3.11.18 출시.
ssl모듈이 유출된 eMudhra 중간 CA 키를 직접 차단합니다(CVE-2026-115557). tarfile 추출 필터 우회(CVE-2026-114583)도 함께 수정됐습니다. - 10/1 릴리스에서도 tarfile, zipfile, ssl, urllib 관련 CVE 여러 개가 수정됐습니다. 그리고 Python 3.10은 3.10.22를 끝으로 지원이 종료(EOL)됐습니다.
Python 3.11, 3.12, 3.13 최신 보안 릴리스는 소스 전용이라 python.org 설치 파일이 없습니다. 설치 파일이 필요하면 3.14.10이나 3.15.2를 쓰거나, 배포판/Homebrew/uv 등의 패키지를 이용하세요.
확인
# 사용 중인 Python 버전
python3 --version
which -a python3
# pip / certifi 버전 (pip 26.2.2 이상, certifi 2026.10.19 이상이면 OK)
python3 -m pip --version
python3 -m pip show certifi | grep -i version
조치
설치 방식별로 업데이트합니다. 사용하는 방식만 골라서 실행하세요.
# Homebrew (macOS)
brew update && brew upgrade python@3.14
# pyenv
pyenv update
pyenv install 3.14.10
pyenv global 3.14.10
# uv (uv 자체도 0.13.5 이상으로)
uv self update
uv python install --reinstall 3.14
# Ubuntu / Debian (배포판 보안 업데이트로 반영)
sudo apt update && sudo apt install --only-upgrade python3 ca-certificates
# Docker 베이스 이미지는 태그를 올리고 다시 빌드
# FROM python:3.14.10-slim
그리고 기존 가상환경마다 pip와 certifi를 따로 올려줘야 합니다. Python 공식 공지에서 안내한 방법은 해시가 고정된 pip 휠로 업그레이드하는 것입니다.
# 가상환경 활성화 후
python -m pip install "pip @ https://files.pythonhosted.org/packages/3f/06/3e4420302363fbb71be3c7f35ce042f54bfca330e3e66b3a2e3c4cca579f/pip-26.2.2-py3-none-any.whl#sha256=fd7f4dfa8190e014013b9f08f3e973f4e4c26ffd179a204895533a7254813a70"
python -m pip install -U certifi
# python.org macOS 설치본이라면 인증서 갱신 스크립트도 실행
# /Applications/Python\ 3.14/Install\ Certificates.command
2. Brotli "Node2Shell" (CVE-2026-111497)
Google Brotli 압축 해제(디코더) 코드에서 조작된 데이터를 풀 때 버퍼 밖에 쓰는 버그가 발견됐습니다. Brotli 1.0.3부터 1.2.0까지가 영향을 받고, 충돌이나 메모리 누수가 생기거나 최악의 경우 원격 코드 실행까지 가능합니다. Node.js, .NET 등과 함께 PyPI의 Brotli, brotlicffi 패키지도 영향을 받습니다.
중요) 코드에서 brotli를 직접 import하지 않아도 위험할 수 있습니다.
Brotli 패키지가 설치돼 있으면 requests/urllib3, aiohttp, httpx[brotli], Scrapy 같은 HTTP 클라이언트가 Content-Encoding: br 응답을 자동으로 풀어줍니다. 그래서 외부 URL을 가져오는 크롤러, 웹훅, 링크 미리보기 같은 기능이 공격 경로가 됩니다. 10/22에 공개 PoC가 나왔고, 실제 공격 사례는 아직 보고되지 않았습니다.
확인
# 설치 여부와 버전 (Brotli < 1.2.1, brotlicffi < 1.2.1.0 이면 취약)
pip show Brotli brotlicffi
# 어떤 패키지가 끌어왔는지
pip install pipdeptree
pipdeptree -r -p Brotli
# lock 파일에 고정돼 있는지
grep -i brotli poetry.lock uv.lock requirements*.txt Pipfile.lock 2>/dev/null
# 시스템 라이브러리 (Debian/Ubuntu)
dpkg -l | grep -i brotli
조치
pip install -U "Brotli>=1.2.1" "brotlicffi>=1.2.1.0"
# lock 파일도 갱신 (안 하면 다음 빌드 때 취약 버전이 다시 설치됨)
uv lock --upgrade-package brotli # uv
poetry update brotli # poetry
# 시스템 패키지(python3-brotli, libbrotli1 등)는 배포판 업데이트로
sudo apt update && sudo apt upgrade
당장 올릴 수 없다면 Brotli 패키지를 지우는 것도 방법입니다. requests, aiohttp 등은 gzip/deflate로 자동 대체됩니다. 이때 httpx[brotli] 같은 extras도 빼야 다음 설치 때 다시 깔리지 않습니다.
pip uninstall -y Brotli brotlicffi
참고로 공개 직후에는 pip-audit, Dependabot 같은 도구가 PyPI 패키지 버전을 제대로 잡아내지 못했다고 하니 직접 버전을 확인하는 게 확실합니다.
3. Pillow 13.0.0 보안 릴리스 (CVE-2026-112900 외)
Python 이미지 처리 라이브러리 Pillow가 10/16에 13.0.0을 내면서 치명적(critical) 등급을 포함한 여러 취약점을 수정했습니다.
- CVE-2026-112900 (EPS): EPS 이미지를 열 때 Ghostscript(
gs)에 파일명을 그대로 넘겨서, 공격자가 파일명을 조작하면 OS 명령을 실행할 수 있습니다. Pillow 2.6.0부터 12.3.0까지 해당되고,gs가 설치된 서버에서만 발생합니다. - FlashPix(FPX):
olefile이 설치돼 있으면 조작된 파일 하나를Image.open()하는 것만으로 명령 실행이 시연됐습니다. Pillow는 확장자가 아니라 내용으로 포맷을 판단하기 때문에 업로드 서버가 위험합니다. - CVE-2026-112403: 조작된 무손실 JPEG의 썸네일을 만들 때 버퍼 오버플로가 일어납니다.
- CVE-2026-112393: 압축 TIFF를 파일이 아닌 메모리(BytesIO)로 저장할 때 버퍼 오버플로가 일어납니다.
확인 및 조치
pip show Pillow | grep -i version
# Pillow 13은 Python 3.10을 지원하지 않으므로 3.11 이상 필요
pip install -U "Pillow>=13.0.0"
# 업로드를 처리하는 서버에 Ghostscript / olefile이 있는지 확인
which gs
pip show olefile
바로 올리기 어렵다면 업로드 처리 서버에서 gs를 제거하고, 코드에서 허용할 포맷을 명시적으로 제한해두면 EPS/FPX 경로를 막을 수 있습니다.
from PIL import Image
# 허용 포맷을 명시해서 EPS, FPX 등은 아예 열지 않도록
ALLOWED = ["JPEG", "PNG", "WEBP", "GIF"]
with Image.open(upload_file, formats=ALLOWED) as im:
im.load() # 썸네일 전에 먼저 load()
im.thumbnail((512, 512), reducing_gap=None)
4. LiteLLM 1.107.0 공급망 공격
LLM 게이트웨이로 많이 쓰는 LiteLLM의 릴리스 파이프라인이 탈취되어, 10/21에 악성 코드가 들어간 litellm 1.107.0이 PyPI와 공식 Docker 이미지로 배포됐습니다.
- PyPI:
litellm==1.107.0(10/21 11:39 ~ 13:23 UTC, 한국 시간 20:39 ~ 22:23) - Docker Hub / GHCR:
v1.107.0,latest,main-latest,main-stable태그 (11:46 ~ 14:20 UTC) - 패키지가
cook.pth,cook.py,sitecustomize.py를 site-packages에 심습니다. 그래서 litellm을 import하지 않아도 Python을 실행하기만 하면 클라우드 키, SSH 키, API 키, 브라우저 데이터 등을 수집해 외부로 전송합니다.
주의) 감염이 의심되는 환경에서 python이나 pip을 실행하면 악성 코드가 다시 실행됩니다. pip show로 확인하지 말고 쉘에서 파일부터 확인하세요.
확인 (python 실행 없이)
# 악성 파일 / 설치 흔적 검색
sudo find / -path "*-packages*" \( -name "litellm-1.107.0.dist-info" -o -name "cook.pth" -o -name "cook.py" -o -name "sitecustomize.py" \) 2>/dev/null
# 백그라운드 로더가 사용하는 잠금 파일
ls -la /tmp/remote_code_loader.lock 2>/dev/null
# lock 파일 / requirements 에 1.107.0이 있는지
grep -rn "litellm" requirements*.txt uv.lock poetry.lock 2>/dev/null | grep "1.107.0"
# Docker 이미지 digest 확인 (sha256:1bbcb1443bc9... 이면 감염 이미지)
docker images --digests | grep -i litellm
정상 패키지 중에도 sitecustomize.py가 있을 수 있으니, 찾은 파일은 내용을 열어서 확인하세요. 파일이 나오지 않았다고 안전하다는 보장은 없습니다. 컨테이너가 재시작되거나 /tmp가 정리되면 흔적이 사라지기 때문입니다.
조치
# 1) 쉘에서 악성 파일 삭제 (SP = 감염된 site-packages 경로)
SP=/path/to/.venv/lib/python3.12/site-packages
rm -f "$SP/cook.pth" "$SP/cook.py" "$SP/sitecustomize.py"
find "$SP" -path "*__pycache__*" \( -name "cook*.pyc" -o -name "sitecustomize*.pyc" \) -delete
# 2) 백그라운드 로더 프로세스 종료
sudo lsof /tmp/remote_code_loader.lock
sudo kill -9 <PID>
# 3) 가상환경은 지우고 새로 만드는 것을 권장
rm -rf .venv
python3 -m venv .venv && . .venv/bin/activate
pip install "litellm==1.106.2" # 공지 기준 안전 버전으로 고정
# 4) 캐시에 남은 1.107.0 제거
pip cache purge
uv cache clean litellm
그리고 가장 중요한 것은 깨끗한 다른 PC에서 자격증명 교체입니다. 외부 인터넷이 되는 호스트에 1.107.0이 설치됐었다면 유출됐다고 가정해야 합니다.
- LLM 제공사 API 키(OpenAI, Anthropic 등), LiteLLM 마스터 키 / 가상 키, 프록시 DB에 저장된 키
- AWS/GCP/Azure 자격증명, 인스턴스 IAM 역할, Kubernetes 서비스 계정, Docker 레지스트리 토큰
- GitHub/GitLab 토큰, CI/CD 시크릿, SSH/GPG 키,
DATABASE_URL비밀번호, 환경변수에 있던 모든 시크릿 - AWS라면 CloudTrail에서 설치 시점 전후의
GetCallerIdentity호출과 외부에서의 자격증명 사용 흔적을 확인
5. 앞으로를 위한 기본 점검
이번 LiteLLM 건처럼 .pth 파일은 Python이 시작될 때마다 자동 실행될 수 있습니다. 가끔 site-packages에 import로 시작하는 .pth 파일이 있는지 확인해보면 좋습니다. (setuptools, editable 설치 등 정상적인 것도 있으니 내용을 확인하세요.)
# site-packages 위치 확인 후 import 문이 있는 .pth 파일 찾기
SP=$(python3 -c "import sysconfig; print(sysconfig.get_paths()['purelib'])")
grep -l "^import" "$SP"/*.pth 2>/dev/null
그리고 의존성 취약점 점검 도구를 CI에 넣어두고, 버전은 해시까지 고정하는 습관을 들이면 공급망 공격 피해를 줄일 수 있습니다.
# 알려진 취약점 점검
pipx run pip-audit
# 해시 고정 requirements 생성 및 설치 (pip-tools)
pip-compile --generate-hashes requirements.in
pip install --require-hashes -r requirements.txt
6. 체크리스트
| 점검 항목 | 확인 명령 | 조치 기준 |
| Python 버전 | python3 --version |
3.14.10 / 3.15.2 / 3.13.18 / 3.12.16 / 3.11.18 이상, 3.10은 EOL |
| pip / certifi | pip show certifi |
pip 26.2.2+, certifi 2026.10.19+ |
| uv | uv --version |
0.13.5 이상 |
| Brotli | pip show Brotli brotlicffi |
Brotli 1.2.1+, brotlicffi 1.2.1.0+ |
| Pillow | pip show Pillow |
13.0.0 이상 (Python 3.11+) |
| LiteLLM | find로 cook.pth 검색 |
1.107.0 흔적 있으면 재구축 + 키 전면 교체 |
| lock 파일 | uv lock / poetry update |
취약 버전 고정 해제 후 재생성 |
| Docker 이미지 | docker images --digests |
베이스 이미지 갱신 후 재빌드 |
참고 자료
- Python Insider - Python 3.15.2, 3.14.10, 3.13.18, 3.12.16, 3.11.18 (10/26)
- Python Insider - Python 3.15.1, 3.14.9, 3.13.17 (10/21)
- Python Insider - Python 3.10.22 ~ 3.14.8 (10/1)
- Broccoli2Shell / Node2Shell - Brotli CVE-2026-111497
- Pillow 13.0.0 릴리스 노트
- The Hacker News - Critical Flaw in Pillow
- LiteLLM - Security Incident Oct 21, 2026
- Microsoft Security Blog - LiteLLM 1.107.0 supply chain compromise
※ 이 글은 2026년 10월 27일 기준 공개된 정보를 정리한 것입니다. 버전이나 조치 내용은 이후 공식 공지에 따라 바뀔 수 있으니 각 프로젝트의 공지를 함께 확인해주세요.
'프로그래밍 > 기타' 카테고리의 다른 글
| Node.js 10월 보안 릴리스 정리 (Brotli RCE CVE-2026-111497 외)와 업그레이드 방법 (0) | 2026.10.27 |
|---|---|
| Tailscale SSH 보안 이슈(Tailworm) 정리 및 패치 전 대응 방법 (0) | 2026.10.27 |
| 한 개의 키보드/마우스로 여러 컴퓨터를 멀티 모니터 처럼 사용하기 (0) | 2024.05.26 |
| 집 PC/서버를 이용한 Public Service 구성 (2) | 2024.01.01 |
| VS Code 열려있는 창 모두 닫기 (전체 단축키 다운로드) (0) | 2023.03.20 |