2 điểm bởi GN⁺ 28 ngày trước | 1 bình luận | Chia sẻ qua WhatsApp
  • Hai phiên bản gói PyPI (1.82.7, 1.82.8) của LiteLLM, thư viện tích hợp LLM được sử dụng rộng rãi, đã bị cài cắm payload độc hại và phát tán, dẫn đến cuộc tấn công đánh cắp thông tin xác thực hệ thống khi cài đặt
  • Nguyên nhân của cuộc tấn công bắt nguồn từ sự cố xâm phạm chuỗi cung ứng của Trivy, công cụ quét bảo mật CI/CD; thông tin xác thực CircleCI bị lộ khiến token phát hành PyPI và GitHub PAT bị đánh cắp
  • Người dùng ảnh Docker Proxy chính thức của LiteLLM không bị ảnh hưởng vì requirements.txt đã khóa phiên bản, nhưng các môi trường cài trực tiếp bằng pip install từ PyPI cần được kiểm tra ngay
  • Trong luồng issue trên GitHub, hàng trăm bình luận spam từ bot đã tràn vào, cản trở thảo luận thực chất; điều này được xác nhận là nỗ lực cố ý của kẻ tấn công nhằm gây nhiễu truyền thông ứng phó
  • Nhiều dự án phụ thuộc LiteLLM như DSPy, CrewAI cũng chịu ảnh hưởng dây chuyền, một lần nữa làm nổi bật lỗ hổng mang tính nền tảng của bảo mật chuỗi cung ứng phần mềm

Tổng quan sự cố và quá trình phát hiện

  • Trong lúc thiết lập dự án mới, hệ thống hoạt động bất thường, RAM bị cạn kiệt và xuất hiện các tiến trình dạng fork bomb
  • Kết quả điều tra cho thấy trong proxy_server.py có thêm một blob độc hại được mã hóa base64, được giải mã để tạo tệp riêng rồi thực thi
  • Phiên bản 1.82.7 chứa payload trong litellm/proxy/proxy_server.py, nên sẽ chạy khi import litellm.proxy
  • Phiên bản 1.82.8 còn bổ sung tệp litellm_init.pth, khiến mã độc tự động chạy khi Python khởi động chỉ cần gói được cài đặt
    • Tệp .pth là cơ chế mà mô-đun site của Python tự động thực thi khi khởi động, cho phép chạy mã tùy ý sau từ khóa import
    • Cơ chế này đã tồn tại từ Python 2.1 và được đưa vào mà không có PEP riêng
  • Nhóm FutureSearch là bên đầu tiên báo cáo bị ảnh hưởng: sau khi uvx tự động cài litellm mới nhất (không khóa phiên bản), Cursor tự động nạp máy chủ MCP cục bộ và dẫn đến lây nhiễm

Đường tấn công và liên hệ với TeamPCP

  • Cuộc tấn công được xác định là do cùng tác nhân với nhóm TeamPCP, nhóm gần đây đã xâm phạm Trivy
  • Chuỗi xâm nhập: hack Trivy → rò rỉ toàn bộ thông tin xác thực CircleCI → đánh cắp token phát hành PyPI + GitHub PAT → phát tán gói độc hại
  • Tài khoản GitHub của CEO/CTO LiteLLM cũng bị chiếm hoàn toàn; mô tả các kho cá nhân đều bị đổi thành "teampcp owns BerriAI" và các issue bị đóng, cùng các hành vi khác
  • Token PYPI_PUBLISH được lưu dưới dạng biến môi trường trong dự án GitHub và bị rò rỉ qua Trivy
    • Tài khoản có bật 2FA, nhưng vẫn bị vượt qua do chính token bị đánh cắp
  • Kẻ tấn công dùng hàng trăm tài khoản bot đăng lặp lại cùng một câu trên issue GitHub để cản trở thảo luận thực chất
    • Trong kho Trivy cũng ghi nhận hơn 700 bình luận spam theo cùng mẫu
    • Một số tài khoản spam là người dùng GitHub có lịch sử đóng góp thật; từ tháng 2 đã có các commit "Update workflow configuration" để cài trình đánh cắp thông tin xác thực vào workflow CI
  • Sự cố xâm phạm Trivy đã xảy ra ít nhất 5 ngày trước, và do thông báo tấn công mới nhất chỉ xuất hiện vào ngày hôm trước nên có thể maintainer chưa kịp nhận biết khi thiệt hại xảy ra
  • Kẻ tấn công còn dùng Internet Computer Protocol (ICP) Canisters để phát payload, nên chặn DNS đơn thuần không đủ để phòng vệ

Cách payload độc hại hoạt động

  • Tạo tiến trình Python chạy nền, giải mã các stage nhúng sẵn rồi thực thi
  • Trình thu thập thông tin xác thực được chạy; khi thu thập dữ liệu thành công, khóa AES sẽ được mã hóa bằng khóa công khai RSA của kẻ tấn công, sau đó dữ liệu đánh cắp được gửi tới máy chủ từ xa
  • Các URL được tìm thấy trong mã độc: checkmarx.zone/rawmodels.litellm.cloud
  • Mục tiêu chính là khóa SSH và thông tin ví crypto trong ~/.git-credentials
  • Do tạo tải CPU rất nặng nên hệ thống bị quá tải, vô tình khiến việc phát hiện dễ hơn; cũng có trường hợp nhận ra bất thường nhờ tiếng quạt máy
  • Khi cài Harbor cũng xuất hiện triệu chứng tương tự: tiến trình grep -r rpcuser\rpcpassword chạy kiểu fork bomb để tìm kiếm ví crypto

Ứng phó của đội ngũ LiteLLM

  • Các phiên bản bị ảnh hưởng (v1.82.7, v1.82.8) đã được xóa khỏi PyPI
  • Đổi mật khẩu cho toàn bộ tài khoản maintainer, xóa và thay thế mọi khóa của GitHub/Docker/CircleCI/pip
  • Tài khoản maintainer mới được thay bằng @krrish-berri-2@ishaan-berri
  • Toàn bộ gói trên PyPI từng bị cách ly tạm thời (quarantine), rồi được gỡ sau khi loại bỏ phiên bản nhiễm độc
  • Dừng mọi bản phát hành mới và đóng băng việc phát hành cho đến khi hoàn tất rà soát toàn bộ chuỗi cung ứng
  • Đang phối hợp với đội bảo mật Mandiant của Google để điều tra và khôi phục
  • Trivy được khóa về phiên bản an toàn cuối cùng là v0.35.0 (ban đầu khóa v0.69.3 rồi đổi theo phản hồi cộng đồng)
  • Đang xem xét tăng cường bảo mật như chuyển sang Trusted Publishing (OIDC dựa trên JWT), dùng tài khoản PyPI riêng, v.v.
  • Thời điểm đăng đầu tiên của phiên bản độc hại là khoảng UTC 8:30, còn thời điểm PyPI cách ly là khoảng UTC 11:25

Phạm vi ảnh hưởng và các dự án downstream

  • LiteLLM là thư viện gọi provider LLM duy nhất của DSPy, còn CrewAI cũng dùng nó làm phương án dự phòng
  • Airflow, Dagster, Unsloth.ai, Polar, nanobot cũng phụ thuộc vào LiteLLM
  • Theo tìm kiếm trên GitHub, có hơn 628 dự án đưa LiteLLM vào requirements.txt mà không khóa phiên bản
  • Người dùng đường phát hành Proxy Docker chính thức không bị ảnh hưởng vì requirements.txt đã khóa phiên bản
  • Với triển khai Docker, quyền truy cập vào hệ thống tệp máy chủ và biến môi trường bị hạn chế nên tương đối an toàn hơn, nhưng thông tin xác thực được mount vào vẫn còn rủi ro
    • Mục tiêu chính của kẻ tấn công là khóa SSH cá nhân; quyền truy cập khóa LLM chỉ là thứ yếu
  • Người dùng các công cụ như Harbor, browser-use vốn tự động cài LiteLLM như một phụ thuộc cũng đã báo cáo thiệt hại gián tiếp
  • CrewAI đã khóa litellm ở 1.82.6 (phiên bản an toàn cuối cùng) nhưng thông điệp commit không nhắc đến sự cố xâm phạm
  • DSPy đang tạo issue công khai để xử lý
  • LangChain có lớp gọi provider LLM riêng nên không bị ảnh hưởng trực tiếp bởi sự cố chuỗi cung ứng lần này (trừ khi dùng gói tùy chọn langchain-litellm)

Thảo luận cộng đồng: bảo mật chuỗi cung ứng và sandbox

  • Không thể tin cậy phụ thuộc và môi trường phát triển như trước nữa; cần phòng thủ nhiều lớp (defense in depth) như cô lập bằng VM + primitive container + allowlist + lọc egress + seccomp + gVisor
  • Tình hình hiện nay là sự quay lại của chủ nghĩa tiện lợi lấn át bảo mật suốt 50 năm qua, đòi hỏi thiết kế lại toàn bộ mô hình an ninh
  • Có ý kiến cho rằng cần sandbox ở cấp ngôn ngữ lập trình cho từng mô-đun
    • Java từng có tính năng này từ thập niên 1990, từ v1.2, nhưng bị loại bỏ vì vấn đề khả dụng
    • Cũng có ý kiến cho rằng đã đến lúc phát triển ngôn ngữ dựa trên capability
    • Runtime workerd của Cloudflare được nhắc tới như một giải pháp hiện có cho cô lập mô-đun
  • Các công cụ cô lập ở cấp hệ điều hành như pledge/unveil của OpenBSD, chroot/namespace/cgroup của Linux, hay Capsicum của FreeBSD vốn đã tồn tại
  • Guix có thể tạo container cô lập chỉ trong vài giây để cài phụ thuộc mà không cần truy cập $HOME
  • Cần tích cực dùng các công cụ cô lập ở user space như Firejail và bwrap
  • Mô hình sandbox + quyền hạn (Intents) của ứng dụng di động đã tồn tại từ lâu, nhưng trên desktop vẫn có tâm lý phản đối việc hạn chế tính toán chung
    • Đáp lại, nhiều ý kiến cho rằng tính đóng của App Store của Apple/Meta và sandbox bảo mật là hai vấn đề khác nhau; vẫn có thể xây công cụ vừa an toàn vừa trao quyền kiểm soát cho người dùng
  • Công cụ canary/honeypot cho macOS đã được công bố (github.com/dweinstein/canary): mount secret giả vào WebDAV/NFS để phát hiện truy cập bất thường
  • Có ý kiến cho rằng cần dựng bức tường giữa việc phát hành gói và kho công khai: nếu đặt kho công khai làm Trusted Publisher trực tiếp thì bề mặt tấn công sẽ rộng hơn
    • Ý kiến phản biện cho rằng mục tiêu gốc của Trusted Publishing là cung cấp liên kết có thể kiểm toán giữa mã nguồn và artifact phát hành, nên việc đi qua kho riêng là một bước lùi

Khuyến nghị bảo mật thực tiễn

  • Phụ thuộc phải khóa phiên bản kèm checksum SHA256
  • Vận hành gương gói nội bộ để tránh dùng trực tiếp phiên bản mới nhất
  • Nên dùng artifact build và tránh phụ thuộc vào cài đặt tức thời khi triển khai bằng uv run hoặc tương tự
    • Cách này cũng loại bỏ rủi ro cấu trúc khi hệ thống bị ngừng vì PyPI gặp sự cố
    • Lợi ích của artifact có thể triển khai: dễ kiểm toán, rollback nhanh, và có thể chặn các endpoint rủi ro trên mạng đi ra ngoài
  • Có thể dùng cấu hình exclude-newer của uv để loại trừ các gói mới trong một khoảng thời gian nhất định
    • Có thể cấu hình [tool.uv] exclude-newer = "5 days" trong pyproject.toml
  • Về căn bản, token phát hành trong CI/CD nên được loại bỏ bằng cách chuyển sang workflow dựa trên OIDC
    • Cả GitHub và PyPI đều hỗ trợ OIDC: nếu chỉ cấp quyền truy cập endpoint OIDC cho tác vụ phát hành thì tác vụ Trivy sẽ không còn token nào để đánh cắp
  • Các công cụ quét bảo mật như Trivy nên chạy trên worker riêng không có quyền phát hành
  • Cần quản lý lockfile và cập nhật theo chu kỳ hàng tuần để tránh nhận bản mới nhất ngay lập tức
  • Tệp .pth của Python có thể tự động thực thi mã; có thể dùng tùy chọn -S để chặn import site, nhưng sẽ có vấn đề tương thích
  • Khuyến nghị dùng osv-scanner và công cụ tương tự để quét toàn bộ phụ thuộc của dự án
  • Lệnh kiểm tra lây nhiễm:
    • find / -name "litellm_init.pth" -type f 2>/dev/null
    • find / -path '*/litellm-1.82.*.dist-info/METADATA' -exec grep -l 'Version: 1.82.[78]' {} \; 2>/dev/null
  • Cũng xuất hiện ý kiến cho rằng cần xoay vòng đồng loạt thông tin xác thực trên toàn bộ hệ sinh thái trình quản lý gói

Vấn đề kiểm toán SOC2 và độ tin cậy

  • Có ý kiến chỉ ra rằng đơn vị kiểm toán SOC2 của LiteLLM là Delve, công ty gần đây vướng tranh cãi
  • SOC2 chỉ xác nhận rằng tổ chức có thực sự tuân theo quy trình đã được tài liệu hóa hay không, chứ không đảm bảo bản thân mức độ bảo mật
  • Ngay cả một quy trình SOC2 phù hợp cũng chưa chắc đã ngăn được cuộc tấn công chuỗi cung ứng lần này

Các dự án thay thế LiteLLM

  • Bifrost (github.com/maximhq/bifrost): phương án thay thế viết bằng Rust, có thể cấu hình khóa ảo cả trên bản mã nguồn mở miễn phí
  • Portkey (portkey.ai): dịch vụ proxy, có gói miễn phí, được đánh giá là nhanh hơn LiteLLM
  • pydantic-ai: phương án thay thế dựa trên Python
  • any-llm (github.com/mozilla-ai/any-llm): dự án của Mozilla
  • LLM Gateway (llmgateway.io): cung cấp hướng dẫn di trú từ LiteLLM
  • InferXgate (github.com/jasmedia/InferXgate): dự án mới, số provider được hỗ trợ còn hạn chế
  • Một số nhà phát triển cho rằng API của các nhà cung cấp LLM trên thực tế chỉ xoay quanh OpenAI và Anthropic, nên gọi trực tiếp bằng requests.post() sẽ an toàn hơn
    • Ý kiến phản biện là API tương thích OpenAI của Anthropic không được khuyến nghị như giải pháp dài hạn/production, và API native theo từng vendor có các tính năng riêng không thể ánh xạ vào API OpenAI

1 bình luận

 
Ý kiến trên Hacker News
  • Tôi là maintainer của LiteLLM. Hiện vẫn đang điều tra vụ việc, nhưng những gì đã xác định được đến lúc này như sau

    1. Có vẻ vấn đề bắt nguồn từ trivy được dùng trong CI/CD (liên kết tìm kiếm liên quan, bài phân tích)
    2. Nếu dùng proxy docker thì không bị ảnh hưởng. Lý do là đã khóa phiên bản trong requirements.txt
    3. Gói đó đã bị cách ly trên PyPI nên việc tải xuống đã bị chặn
      Hiện chúng tôi đang xem xét nguyên nhân gốc rễ và các biện pháp tăng cường bảo mật, xin lỗi vì đã gây bất tiện
    • Các phiên bản bị ảnh hưởng (v1.82.7, v1.82.8) đã bị xóa khỏi PyPI. Tất cả tài khoản maintainer và khóa (GitHub, Docker, CircleCI, pip) đã được thay thế. Chúng tôi vẫn đang quét toàn bộ dự án và rất hoan nghênh sự hỗ trợ từ các chuyên gia bảo mật (liên hệ: krrish@berri.ai)
    • Có người nói rằng tài khoản GitHub cá nhân của tôi dường như cũng đã bị xâm phạm. Trong kết quả tìm kiếm có thể thấy dấu vết liên quan
    • Cảm ơn vì đã nói rằng cách tôi nói “xin lỗi” nghe rất con người. Phản hồi rằng ứng phó chân thành tốt hơn một thông báo xin lỗi mang tính hình thức là nguồn động viên lớn
    • Có câu hỏi vì sao việc xoay vòng thông tin xác thực không được thực hiện ngay lập tức. Có lẽ tôi cần giải thích vì sao đã không nhận ra điều đó trong thời gian ngắn
    • Có người đã tạo và chia sẻ một script đơn giản để tìm phiên bản litellm đã cài trên hệ thống của mình (liên kết script). Nó không hoàn hảo nhưng có thể quét nhanh conda, .venv, uv và môi trường hệ thống
  • Chúng ta vẫn không thể tin tưởng hoàn toàn vào dependency và môi trường phát triển. Dev container cách ly chưa đủ và cũng kém tiện dụng. Giờ cần chuyển sang môi trường phát triển dựa trên sandbox. Cần một môi trường có mức cách ly cỡ VM, lọc egress, seccomp và các lớp phòng vệ như gVisor. Với môi trường như vậy, kể cả khi bị xâm phạm thì container cũng sẽ bị dừng ngay và có thể dễ dàng xác định vấn đề

    • Có cảm giác như thói quen cắt góc trong bảo mật suốt 50 năm qua giờ đang quay lại phản tác dụng. Văn hóa phát triển dựa trên niềm tin có lẽ đang đi đến hồi kết. Không chỉ sandboxing đơn thuần, mà cần thiết kế lại chính mô hình bảo mật
    • Giờ không thể nói “như ngày xưa” nữa. Độ an toàn có thể xác minh bằng mật mã học là điều bắt buộc. Cần tiến tới hướng như DISA STIG của Red Hat, tức là cấm dùng kho lưu trữ bên ngoài
    • Có người xin ý kiến về dự án của mình nhằm tách biệt thông tin xác thực khỏi container (tightbeam, airlock)
    • Tôi đang phát triển một dự án mã nguồn mở tên smolvm (liên kết). Đây là công nghệ kết hợp mức cách ly kiểu VM với hỗ trợ container, hướng tới triển khai theo đơn vị máy ảo hoàn chỉnh. Tôi đang tìm người cùng hợp tác
    • Có câu hỏi liệu trong các vụ tấn công chuỗi cung ứng gần đây đã thực sự có trường hợp thoát khỏi dev container hay chưa
  • Giới thiệu công cụ canary tôi làm cho macOS (liên kết). Đây là một binary Go đơn giản để phát hiện khi package truy cập vào các tệp mà nó không nên chạm tới. Nó phơi bày thông tin bí mật giả qua WebDAV hoặc NFS và gửi cảnh báo khi có truy cập. Có thể phát hiện hành vi bất thường bằng cách tiếp cận honeypot

  • Đây là vụ việc liên quan đến hoạt động của TeamPCP trong vài tuần gần đây. Timeline tôi tổng hợp có thể sẽ hữu ích

    • Có phản hồi rằng đây là bản tổng hợp rất tốt. Tuy vậy cũng có người đùa rằng “playlist” mới là thứ gây ấn tượng
    • Có phản ứng rằng đã thấy cái tên TeamPCP ở nhiều nơi, nhưng đây là lần đầu tiên mọi thứ được sắp xếp gọn gàng để nhìn một lượt
    • Có câu hỏi làm thế nào để có thể cập nhật nhanh như vậy
  • Có ý kiến chỉ ra rằng hệ thống phát hiện spam của GitHub quá yếu. Họ nói rằng issue của litellm đã có hơn 170 bình luận spam

    • Chuyện tương tự cũng xảy ra ở repo trivy vài ngày trước. Sau khi cuộc thảo luận về vụ hack bị đóng lại, đã xuất hiện hơn 700 bình luận spam. Một số đến từ các tài khoản có lịch sử hoạt động thật. Có vẻ kiểu tấn công đánh cắp thông tin xác thực đang lan rộng trên diện rộng. Trên nhiều tài khoản có dấu vết đã cài credential stealer vào CI thông qua commit “Update workflow configuration” vào tháng 2
    • Có phàn nàn rằng để báo cáo spam trên GitHub phải qua quá nhiều bước nên không hiệu quả
    • Cũng có nhắc đến khả năng một số chỉ là tài khoản bot đơn thuần
  • Tôi đã đoán chuyện như thế này rồi cũng sẽ xảy ra. Tôi đã cố phòng thủ bằng cách khóa phiên bản dependency, nhưng ngay cả vậy cũng không hoàn hảo. Vì độ phức tạp của chuỗi cung ứng trong mã nguồn mở, việc xác minh mọi dòng mã là bất khả thi. Nhờ LLM, nguy cơ mã độc lan tràn hàng loạt đã tăng lên gấp 100 lần

    • Có ý kiến rằng hệ sinh thái Rust quá khó xác minh vì cây dependency quá sâu. Rust, Node và Python đều gặp vấn đề tương tự. Trong khi đó C/C++ tương đối an toàn hơn vì dùng trình quản lý gói hệ thống nên chi phí thêm dependency cao hơn
  • Nếu mã do AI viết có thể xâm nhập vào LLVM hoặc Linux, chúng ta sẽ thật sự đối mặt với vấn đề “trusting trust”

    • Vấn đề “Trusting Trust” thực ra đã có hướng giải bằng phương pháp Diverse Double-Compiling. Nhưng tấn công chuỗi cung ứng vẫn là bài toán khó. AI chỉ là công cụ khuếch đại quy mô tấn công mà thôi
    • Giờ mọi thứ đều khiến người ta bất an. Có lẽ chỉ môi trường airgap mới an toàn. Nhưng phần lớn dữ liệu lại nằm trên cloud, và chúng ta thậm chí không kiểm soát được cả bản sao lưu của chúng
    • Đang có những nỗ lực tạo ra phần mềm có thể xác minh hoàn toàn nhờ chuỗi build quyết định. 93% gói của Debian là build có thể tái tạo. Nhưng vẫn còn rất nhiều lập trình viên thản nhiên chạy “curl | bash”. Sự cố backdoor XZ là một ví dụ đã đánh thức mọi người về thực tế này
    • Cũng có ý kiến cho rằng cách phòng thủ duy nhất là thay đổi API nội bộ thường xuyên để LLM không thể học được mã kernel
    • Nếu kiểu tấn công này trở thành hiện thực, máy chủ chính phủ hoặc hạ tầng cloud có thể chịu thiệt hại quy mô lớn. Đặc biệt nếu kết hợp với các cuộc tấn công cấp quốc gia thì thiệt hại có thể lên tới hàng nghìn tỷ đô la. Dù vậy, tôi vẫn cho rằng Linux tương đối an toàn hơn
  • Có nhắc đến việc đơn vị kiểm toán SOC2 của LiteLLM là Delve.

    • Tuy nhiên, vẫn còn nghi ngờ liệu chứng nhận SOC2 có thể ngăn được kiểu tấn công này hay không. Cũng có chia sẻ từ trải nghiệm thực tế rằng SOC2 không phải là tấm khiên tuyệt đối
  • Sau khi cài Harbor, CPU tăng vọt lên 100% và hệ thống bị treo. Có vẻ tiến trình grep -r rpcuser\rpcpassword đã cố tìm ví tiền mã hóa. May là backdoor chưa được cài vào

    • Có người nói họ cũng gặp trải nghiệm tương tự với browser-use. litellm được cài như một dependency và hệ thống bị treo. Họ đã vô hiệu hóa token GitHub và HuggingFace nhưng hỏi liệu có cần cài lại hệ điều hành không
    • Có câu hỏi “làm sao bạn kiểm tra được tiến trình nhanh đến vậy”. Họ tò mò không biết có phải luôn bật Activity Monitor không
    • Cũng có câu hỏi “Harness là gì”
  • Có vẻ vụ việc lần này là do cùng nhóm tấn công TeamPCP đã hack Trivy thực hiện. Việc issue ngập bot comment cũng là cùng một kiểu mẫu. Khả năng cao đây là cuộc tấn công tự động hóa có dùng LLM

    • Có câu hỏi vì sao kẻ tấn công lại spam bot comment để lấp đầy issue. Có lẽ mục đích là gây nhiễu và làm chậm phản ứng ứng phó