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

CVELỗiBản bị ảnh hưởngĐiều kiện kích hoạt
CVE-2026-112398Tràn heap khi giải mã FlashPix (FPX)12.3.0 trở về trướcImage.open() tệp FPX, có cài olefile
CVE-2026-112403Tràn heap khi giải mã JPEG12.3.0 trở về trướcthumbnail() hoặc draft() trên JPEG lossless độc
CVE-2026-96639Dùng lại vùng nhớ cũ trong bộ đọc ảnh nhiều khung11.0.0 đến 12.3.0Đọc khung của tệp MPO, PSD, DCX, MIC
CVE-2026-112900Chèn tham số vào lệnh Ghostscript2.6.0 đến 12.3.0Mở EPS với tên tệp do kẻ tấn công đặt, máy có cài gs
CVE-2026-112393Tràn heap khi lưu TIFF nén2.0.0 đến 12.3.0Lư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ỡ olefile nế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ọi load() 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.

Nguồn tham khảo