Nếu website của bạn viết bằng Django, Flask hoặc FastAPI và cho người dùng tải ảnh lên, hãy kiểm tra phiên bản Pillow. Pillow 13.0.0, phát hành ngày 16/10/2026, sửa hàng loạt lỗ hổng trong thư viện xử lý ảnh phổ biến nhất của Python. Từ 23/10, OX Security và The Hacker News đồng loạt cảnh báo. Lý do: một số lỗi chỉ cần mở một tệp ảnh được dựng đặc biệt là có thể làm hỏng bộ nhớ, và trong một số điều kiện có thể dẫn tới thực thi mã.
Tóm tắt nhanh
- Bản vá: Pillow 13.0.0 (16/10/2026), chỉ hỗ trợ Python 3.11 trở lên.
- Số lỗi: theo GitHub Advisory Database, 41 advisory được sửa, gồm 5 mức Critical, 23 High và 13 Medium.
- Lỗi đáng chú ý: CVE-2026-112398 (FlashPix), CVE-2026-112403 (JPEG), CVE-2026-96639 (ảnh nhiều khung), CVE-2026-112900 (EPS qua Ghostscript), CVE-2026-112393 (TIFF).
- Khai thác: chưa ghi nhận tấn công thực tế, CVE-2026-112393 đã có PoC.
Các CVE chính trong Pillow 13.0.0
| CVE | Lỗi | Bản bị ảnh hưởng | Điều kiện kích hoạt |
|---|---|---|---|
| CVE-2026-112398 | Tràn heap khi giải mã FlashPix (FPX) | 12.3.0 trở về trước | Image.open() tệp FPX, có cài olefile |
| CVE-2026-112403 | Tràn heap khi giải mã JPEG | 12.3.0 trở về trước | thumbnail() hoặc draft() trên JPEG lossless độc |
| CVE-2026-96639 | Dùng lại vùng nhớ cũ trong bộ đọc ảnh nhiều khung | 11.0.0 đến 12.3.0 | Đọc khung của tệp MPO, PSD, DCX, MIC |
| CVE-2026-112900 | Chèn tham số vào lệnh Ghostscript | 2.6.0 đến 12.3.0 | Mở EPS với tên tệp do kẻ tấn công đặt, máy có cài gs |
| CVE-2026-112393 | Tràn heap khi lưu TIFF nén | 2.0.0 đến 12.3.0 | Lưu TIFF vào io.BytesIO, lưu ra tệp thường không bị |
Mức độ nghiêm trọng giữa các nguồn chưa thống nhất. Ví dụ, CVE-2026-112900 được bản ghi CVE trên GitHub chấm 9.2. Trong khi đó, nhóm phát triển Pillow chỉ xếp lỗi này mức trung bình, vì nó bị kích hoạt bởi tên tệp chứ không phải nội dung tệp. Theo The Hacker News, CVE-2026-112403 do Anthropic tìm ra bằng Claude và được Ada Logics xác minh thủ công.
Vì sao lỗi FlashPix đáng lo nhất?
Pillow nhận diện định dạng ảnh dựa trên nội dung, không dựa vào đuôi tệp. Một tệp mang đuôi .jpg vẫn có thể là FlashPix bên trong. Nếu môi trường có cài gói olefile, lệnh Image.open() quen thuộc trong mọi đoạn mã xử lý avatar hay ảnh sản phẩm đã đủ để kích hoạt lỗi.
Cách kiểm tra trên VPS
# Phiên bản Pillow và Python trong môi trường ảo của dự án
python -c "import PIL, sys; print(PIL.__version__, sys.version)"
# Có cài olefile không (điều kiện của CVE-2026-112398)
pip show olefile
# Có Ghostscript không (điều kiện của CVE-2026-112900)
which gs
# Tìm chỗ gọi thumbnail, draft hoặc đọc nhiều khung
grep -rnE "\.thumbnail\(|\.draft\(|ImageSequence|\.seek\(" --include="*.py" .
Nhớ kiểm tra cả image Docker và các worker xử lý ảnh nền như Celery, RQ. Đây thường là nơi bị bỏ quên.
Nâng cấp đúng cách
# Yêu cầu Python 3.11 trở lên
python -m pip install -U "pillow>=13"
# Cập nhật tệp phụ thuộc
pip freeze | grep -i pillow
Theo Convika, trên Python 3.10, lệnh pip install -U pillow sẽ âm thầm giữ bản 12.3.0. Vì vậy cần ghi rõ mốc >=13 để lệnh báo lỗi nếu môi trường không đủ điều kiện.
Lưu ý về gói hệ điều hành. Tính đến bài tổng hợp của Convika, Pillow 13 mới có trên PyPI, conda-forge và Homebrew. Debian chỉ có ở nhánh unstable, Ubuntu còn ở trạng thái "needs-triage". Nếu ứng dụng dùng python3-pil từ apt, hãy theo dõi bản cập nhật của bản phân phối hoặc chuyển sang cài Pillow trong môi trường ảo.
Nếu chưa thể nâng cấp ngay
Các hãng bảo mật gợi ý một số biện pháp tạm thời:
- Gỡ
olefilenếu không có gói nào khác cần tới. - Không cài Ghostscript trên máy xử lý ảnh người dùng tải lên, và từ chối tệp EPS.
- Tránh dùng
thumbnail(),draft()với JPEG không tin cậy, hoặc gọiload()trước. - Lưu TIFF ra tệp trên đĩa thay vì
io.BytesIO. - Không đọc từng khung của ảnh nhiều khung do người dùng gửi lên.
Lưu ý: tham số formats= của Image.open() không chặn được lỗi JPEG. Các biện pháp này chỉ giảm rủi ro, nâng cấp mới là cách xử lý triệt để. Nếu đang dùng Python 3.10, đây là dịp nên lên 3.11 hoặc 3.12.