- แพ็กเกจ PyPI ของ LiteLLM ไลบรารีรวม LLM ที่ใช้งานกันอย่างแพร่หลาย 2 เวอร์ชัน (1.82.7, 1.82.8) ถูก ฝังเพย์โหลดอันตราย และเผยแพร่ออกไป ทำให้เมื่อมีการติดตั้งจะเกิดการโจมตีเพื่อขโมยข้อมูลรับรองของระบบ
- สาเหตุของการโจมตีเริ่มจาก การถูกเจาะห่วงโซ่อุปทานของ Trivy เครื่องมือสแกนความปลอดภัยสำหรับ CI/CD ส่งผลให้ข้อมูลรับรองของ CircleCI รั่วไหล และโทเค็นสำหรับเผยแพร่ขึ้น PyPI กับ GitHub PAT ถูกขโมย
- ผู้ใช้ Proxy Docker image ทางการของ LiteLLM ไม่ได้รับผลกระทบ เนื่องจากมีการตรึงเวอร์ชันไว้ใน requirements.txt แต่สภาพแวดล้อมที่ติดตั้งผ่าน PyPI โดยตรงด้วย pip ควรตรวจสอบทันที
- ในเธรด GitHub issue มี คอมเมนต์สแปมจากบอต หลั่งไหลเข้ามาหลายร้อยข้อความจนรบกวนการพูดคุยจริง โดยยืนยันได้ว่าเป็นความพยายามของผู้โจมตีในการก่อกวนการสื่อสารตอบสนองเหตุการณ์
- เหตุการณ์นี้ลามไปยังหลายโครงการที่พึ่งพา LiteLLM อย่าง DSPy, CrewAI เป็นต้น และตอกย้ำถึง ความเปราะบางพื้นฐานของความปลอดภัยห่วงโซ่อุปทานซอฟต์แวร์ อีกครั้ง
ภาพรวมเหตุการณ์และลำดับการค้นพบ
- ระหว่างตั้งค่าโปรเจ็กต์ใหม่ ระบบเริ่มทำงานผิดปกติ โดย RAM ถูกใช้จนหมด และมีกระบวนการลักษณะฟอร์กบอมบ์ทำงาน
- จากการตรวจสอบพบว่ามีการเพิ่ม บล็อบอันตรายที่เข้ารหัสแบบ base64 เข้าไปใน
proxy_server.py โดยจะถอดรหัสเพื่อสร้างไฟล์แยกอีกไฟล์แล้วจึงรัน
- เวอร์ชัน 1.82.7 มีเพย์โหลดอยู่ใน
litellm/proxy/proxy_server.py และจะ ทำงานเมื่อ import litellm.proxy
- เวอร์ชัน 1.82.8 เพิ่มไฟล์
litellm_init.pth เข้ามาอีก ทำให้เพียงแค่ติดตั้งแพ็กเกจก็เพียงพอที่ Python จะ รันมัลแวร์อัตโนมัติเมื่อเริ่มต้น
- ไฟล์
.pth เป็นกลไกที่โมดูล site ของ Python จะเรียกใช้อัตโนมัติเมื่อเริ่มต้น และสามารถรันโค้ดตามอำเภอใจได้หลังคีย์เวิร์ด import
- กลไกนี้มีอยู่มาตั้งแต่ Python 2.1 โดยถูกเพิ่มเข้ามาโดยไม่มี PEP แยก
- ทีม FutureSearch เป็นผู้รายงานความเสียหายรายแรก: uvx ติดตั้ง litellm เวอร์ชันล่าสุดโดยอัตโนมัติ (ไม่ได้ตรึงเวอร์ชัน) จากนั้น Cursor โหลด local MCP server อัตโนมัติและเกิดการติดเชื้อ
เส้นทางการโจมตีและความเชื่อมโยงกับ TeamPCP
- ยืนยันแล้วว่าการโจมตีนี้เป็นฝีมือของกลุ่ม TeamPCP กลุ่มเดียวกับที่เพิ่งเจาะ Trivy
- เส้นทางการบุกรุก: เจาะ Trivy → ข้อมูลรับรองของ CircleCI รั่วไหลทั้งหมด → ขโมยโทเค็นเผยแพร่ขึ้น PyPI + GitHub PAT → ปล่อยแพ็กเกจอันตราย
- บัญชี GitHub ของ CEO/CTO ของ LiteLLM ก็ถูกยึดเต็มรูปแบบ โดยคำอธิบายของ repository ส่วนตัวทั้งหมดถูกเปลี่ยนเป็น "teampcp owns BerriAI" และมีการปิด issue เป็นต้น
- โทเค็น
PYPI_PUBLISH ถูกเก็บไว้เป็น ตัวแปรสภาพแวดล้อมของโปรเจ็กต์ GitHub และข้อมูลนี้รั่วผ่าน Trivy
- แม้บัญชีจะเปิดใช้ 2FA แต่ผู้โจมตีข้ามการป้องกันนี้ได้เพราะขโมยตัวโทเค็นไปโดยตรง
- ผู้โจมตีใช้ บัญชีบอต หลายร้อยบัญชีโพสต์ข้อความเดิมซ้ำ ๆ ใน GitHub issue เพื่อขัดขวางการสนทนาจริง
- ใน repository ของ Trivy ก็พบรูปแบบเดียวกัน โดยมี คอมเมนต์สแปมมากกว่า 700 รายการ
- บางบัญชีสแปมเป็นผู้ใช้ GitHub จริงที่มีประวัติการมีส่วนร่วม และตรวจพบว่า ตั้งแต่เดือนกุมภาพันธ์มีคอมมิตข้อความ "Update workflow configuration" เพื่อ ฝังตัวขโมยข้อมูลรับรองไว้ใน CI workflow
- การถูกเจาะ Trivy เกิดขึ้นอย่างน้อย 5 วันก่อนหน้า และเนื่องจากประกาศการโจมตีล่าสุดเพิ่งออกมาก่อนหน้าเพียงวันเดียว จึงเป็นไปได้ที่ผู้ดูแลยังไม่รับรู้ก่อนเกิดความเสียหาย
- ผู้โจมตียังใช้ Internet Computer Protocol(ICP) Canisters ในการส่งเพย์โหลด ทำให้ไม่สามารถป้องกันได้ด้วยการบล็อก DNS เพียงอย่างเดียว
วิธีการทำงานของเพย์โหลดอันตราย
- สร้างกระบวนการ Python เบื้องหลัง จากนั้นถอดรหัสสเตจที่ฝังมาแล้วรัน
- จะมีการรัน ตัวรวบรวมข้อมูลรับรอง และเมื่อรวบรวมข้อมูลได้สำเร็จ จะเข้ารหัส AES key ด้วย RSA public key ของผู้โจมตี ก่อนส่งข้อมูลที่ขโมยได้ไปยัง โฮสต์ระยะไกล
- URL ที่พบในมัลแวร์:
checkmarx.zone/raw และ models.litellm.cloud
- เป้าหมายหลักคือการขโมย SSH key ใน
~/.git-credentials และข้อมูลกระเป๋าคริปโต
- งานที่ใช้ CPU หนักทำให้ระบบโอเวอร์โหลดจนกลับยิ่งสังเกตพบได้ง่าย และมีรายงานว่าบางกรณีสังเกตความผิดปกติได้จากเสียงพัดลม
- ตอนติดตั้ง Harbor ก็พบอาการเดียวกัน: มีกระบวนการ
grep -r rpcuser\rpcpassword ทำงานแบบฟอร์กบอมบ์เพื่อพยายาม ค้นหากระเป๋าคริปโต
การตอบสนองของทีม LiteLLM
- เวอร์ชันที่ได้รับผลกระทบ (v1.82.7, v1.82.8) ถูก ลบออกจาก PyPI แล้ว
- เปลี่ยน รหัสผ่าน ของทุกบัญชีเมนเทนเนอร์ และลบ/หมุนเปลี่ยนกุญแจทั้งหมดของ GitHub/Docker/CircleCI/pip
- เปลี่ยนไปใช้บัญชีเมนเทนเนอร์ใหม่คือ @krrish-berri-2 และ @ishaan-berri
- แพ็กเกจทั้งหมดบน PyPI ถูก กักกัน (quarantine) ชั่วคราว ก่อนจะปลดล็อกหลังจากลบเวอร์ชันที่ติดเชื้อแล้ว
- หยุดรีลีสใหม่ทั้งหมด และระงับการเผยแพร่ไว้จนกว่าจะตรวจสอบห่วงโซ่อุปทานทั้งหมดเสร็จสิ้น
- กำลังร่วมมือกับทีมความปลอดภัย Mandiant ของ Google เพื่อตรวจสอบและกู้คืนระบบ
- ตรึง Trivy ไว้ที่เวอร์ชันปลอดภัยล่าสุดคือ v0.35.0 (เดิมตรึงที่ v0.69.3 ก่อนจะเปลี่ยนตามเสียงตอบรับจากชุมชน)
- มีแผนพิจารณาเพิ่มความปลอดภัย เช่น เปลี่ยนไปใช้ Trusted Publishing (OIDC แบบ JWT token) และใช้บัญชี PyPI แยกต่างหาก
- เวลาที่เวอร์ชันอันตรายถูกเผยแพร่ครั้งแรกอยู่ราว UTC 8:30 และ PyPI เริ่มกักกันราว UTC 11:25
ขอบเขตผลกระทบและโปรเจ็กต์ปลายน้ำ
- LiteLLM เป็นไลบรารีเรียกใช้ LLM provider เพียงตัวเดียวของ DSPy และ CrewAI ก็ใช้เป็น fallback เช่นกัน
- Airflow, Dagster, Unsloth.ai, Polar, nanobot ฯลฯ ก็พึ่งพา LiteLLM
- จากการค้นหาใน GitHub พบโปรเจ็กต์มากกว่า 628 รายการที่ใส่ LiteLLM ใน requirements.txt แบบ ไม่ตรึงเวอร์ชัน
- ผู้ใช้เส้นทางแจกจ่าย Proxy Docker อย่างเป็นทางการไม่ได้รับผลกระทบ เพราะ requirements.txt มีการ ตรึงเวอร์ชัน ไว้
- สำหรับการแจกจ่ายผ่าน Docker การเข้าถึงไฟล์ระบบของโฮสต์และตัวแปรสภาพแวดล้อมถูกจำกัด จึงปลอดภัยกว่าในระดับหนึ่ง แต่ข้อมูลรับรองที่ถูก mount เข้าไปยังคงเสี่ยง
- เป้าหมายหลักของผู้โจมตีคือ SSH key ส่วนบุคคล ส่วนการเข้าถึง LLM key เป็นเป้าหมายรอง
- ผู้ใช้เครื่องมืออย่าง Harbor, browser-use ที่ติดตั้ง LiteLLM เป็น dependency โดยอัตโนมัติก็มีรายงานว่าได้รับ ผลกระทบทางอ้อม
- CrewAI ได้ ตรึง litellm ไว้ที่ 1.82.6 (เวอร์ชันปลอดภัยล่าสุด) แต่ในข้อความคอมมิตไม่ได้กล่าวถึงการถูกเจาะ
- DSPy กำลังตอบสนองผ่านการ เปิด issue แบบสาธารณะ
- LangChain มีเลเยอร์เรียกใช้ LLM provider ของตนเอง จึง ไม่ได้รับผลกระทบโดยตรงจากการโจมตีห่วงโซ่อุปทานครั้งนี้ (ยกเว้นกรณีใช้แพ็กเกจเสริม
langchain-litellm)
การถกเถียงในชุมชน: ความปลอดภัยห่วงโซ่อุปทานและการทำแซนด์บ็อกซ์
- ตอนนี้ ไม่สามารถไว้วางใจ dependency และสภาพแวดล้อมการพัฒนาได้อีกต่อไป จึงจำเป็นต้องมี การป้องกันหลายชั้น (defense in depth) เช่น การแยกด้วย VM + primitive ของคอนเทนเนอร์ + allowlist + egress filter + seccomp + gVisor
- สถานการณ์นี้สะท้อนการย้อนกลับของ แนวคิดอำนวยความสะดวกเหนือความปลอดภัยตลอด 50 ปีที่ผ่านมา และชี้ว่าต้องออกแบบโมเดลความปลอดภัยใหม่ทั้งระบบ
- มีความเห็นว่าควรมีการทำแซนด์บ็อกซ์ ในระดับภาษาโปรแกรม แยกตามโมดูล
- Java เคยมีความสามารถนี้มาตั้งแต่ยุค v1.2 ในทศวรรษ 1990 แต่ภายหลังถูกยกเลิกเพราะปัญหาด้านการใช้งาน
- มีผู้เสนอว่านี่คือเวลาที่เหมาะสมสำหรับการพัฒนาภาษาแบบ capability-based
- รันไทม์ workerd ของ Cloudflare ถูกยกเป็นตัวอย่างโซลูชันเดิมที่รองรับการแยกโมดูลได้
- เครื่องมือแยกระดับ OS อย่าง pledge/unveil ของ OpenBSD, chroot/namespace/cgroup ของ Linux, และ Capsicum ของ FreeBSD มีอยู่แล้ว
- Guix สามารถสร้าง คอนเทนเนอร์แยกได้ภายในไม่กี่วินาที เพื่อติดตั้ง dependency โดยไม่เข้าถึง $HOME
- ควรใช้งานเครื่องมือแยกใน user space อย่าง Firejail และ bwrap อย่างจริงจัง
- โมเดล sandboxing + permissions (Intents) ของแอปมือถือมีอยู่แล้ว แต่ในเดสก์ท็อปยังมีแรงต้านต่อการจำกัดการประมวลผลทั่วไปค่อนข้างมาก
- มีข้อโต้แย้งว่า ความปิดของ app store ของ Apple/Meta กับ security sandboxing เป็นคนละเรื่องกัน และยังสามารถสร้างเครื่องมือที่ให้ผู้ใช้ควบคุมได้พร้อมกับรักษาความปลอดภัย
- มีการเผยแพร่ เครื่องมือ canary/honeypot สำหรับ macOS (github.com/dweinstein/canary): mount secret ปลอมผ่าน WebDAV/NFS เพื่อใช้ตรวจจับการเข้าถึงผิดปกติ
- มีความเห็นว่า ควรมีกำแพงกั้นระหว่างการเผยแพร่แพ็กเกจกับ repository สาธารณะ เพราะการตั้ง repository สาธารณะให้เป็น Trusted Publisher โดยตรงจะเพิ่มพื้นผิวการโจมตี
- ข้อโต้แย้งคือ เป้าหมายดั้งเดิมของ Trusted Publishing คือการสร้าง การเชื่อมโยงที่ตรวจสอบย้อนกลับได้ระหว่างซอร์สกับอาร์ติแฟกต์ที่เผยแพร่ ดังนั้นการบังคับให้ผ่าน repository ส่วนตัวจึงเป็นการถอยหลัง
คำแนะนำด้านความปลอดภัยเชิงปฏิบัติ
- ต้อง ตรึงเวอร์ชันของ dependency พร้อม SHA256 checksum
- ควรมี package mirror ภายในองค์กร เพื่อเลี่ยงการใช้เวอร์ชันล่าสุดโดยตรง
- ใช้ build artifact และหลีกเลี่ยงการพึ่งการติดตั้งแบบสดตอนดีพลอย เช่น
uv run
- ยังช่วยลดความเสี่ยงเชิงโครงสร้างที่ระบบจะหยุดทำงานเมื่อ PyPI มีปัญหา
- ข้อดีของ artifact ที่นำไปดีพลอยได้คือ ตรวจสอบย้อนหลังได้, rollback ได้เร็ว, และสามารถบล็อกปลายทางเครือข่ายขาออกที่เสี่ยงได้
- ใช้การตั้งค่า
exclude-newer ของ uv เพื่อ ตัดแพ็กเกจใหม่ภายในช่วงเวลาที่กำหนดออก
- สามารถตั้งค่าใน pyproject.toml ได้ด้วย
[tool.uv] exclude-newer = "5 days"
- ใน CI/CD ควรเปลี่ยนโทเค็นเผยแพร่ไปใช้ workflow แบบ OIDC เพื่อตัดปัญหาโดยการไม่เก็บโทเค็นตั้งแต่ต้น
- ทั้ง GitHub และ PyPI รองรับ OIDC: หากให้สิทธิ์เข้าถึง OIDC endpoint เฉพาะงาน publish ก็จะไม่มีโทเค็นให้ Trivy ขโมยจากงานสแกน
- ควรรันเครื่องมือสแกนความปลอดภัยอย่าง Trivy บน worker แยกที่ไม่มีสิทธิ์ publish
- ควรจัดการ lockfile และอัปเดตรายสัปดาห์เพื่อหลีกเลี่ยงการนำเวอร์ชันล่าสุดมาใช้ทันที
- ไฟล์
.pth ของ Python สามารถ รันโค้ดอัตโนมัติ ได้ ดังนั้นสามารถใช้ตัวเลือก -S เพื่อยับยั้งการ import site ได้ แม้อาจมีปัญหาความเข้ากันได้
- แนะนำให้ใช้ osv-scanner และเครื่องมือคล้ายกันเพื่อสแกน dependency ทั้งโปรเจ็กต์
- คำสั่งตรวจสอบการติดเชื้อ:
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
- ยังมีการเสนอว่าควรมีการ หมุนเปลี่ยนข้อมูลรับรอง (credential rotation) แบบครอบคลุมทั้ง ecosystem ของ package manager
ปัญหาเรื่องการตรวจรับรอง SOC2 และความน่าเชื่อถือ
- มีผู้ชี้ว่า บริษัทที่ทำการตรวจ SOC2 ให้ LiteLLM คือ Delve ซึ่งเพิ่งมีประเด็นถกเถียงเมื่อไม่นานมานี้
- SOC2 เป็นเพียงการตรวจว่าองค์กร ทำตามกระบวนการที่บันทึกไว้จริงหรือไม่ ไม่ได้ รับประกันระดับความปลอดภัย โดยตัวมันเอง
- แม้จะมี SOC2 ที่เหมาะสม ก็ยังไม่แน่ชัดว่าจะป้องกันการโจมตีห่วงโซ่อุปทานครั้งนี้ได้หรือไม่
โปรเจ็กต์ทางเลือกแทน LiteLLM
- Bifrost (github.com/maximhq/bifrost): ทางเลือกที่พัฒนาด้วย Rust และตั้งค่า virtual key ได้แม้บนอินสแตนซ์โอเพนซอร์สฟรี
- Portkey (portkey.ai): บริการพร็อกซี มีแพ็กเกจฟรี และมีผู้ประเมินว่าเร็วกว่า LiteLLM
- pydantic-ai: ทางเลือกบน Python
- any-llm (github.com/mozilla-ai/any-llm): โปรเจ็กต์ของ Mozilla
- LLM Gateway (llmgateway.io): มีคู่มือย้ายออกจาก LiteLLM
- InferXgate (github.com/jasmedia/InferXgate): โปรเจ็กต์ใหม่ที่ยังรองรับ provider จำกัด
- นักพัฒนาบางส่วนมองว่า API ของ LLM provider ในทางปฏิบัติมีเพียง OpenAI กับ Anthropic สองแบบ จึงปลอดภัยกว่าหากเรียกตรงด้วย
requests.post()
- อีกฝ่ายโต้ว่า API ที่เข้ากันได้กับ OpenAI ของ Anthropic ไม่แนะนำสำหรับการใช้งานระยะยาว/ระดับโปรดักชัน และ API แบบเนทีฟของแต่ละ vendor ก็มีความสามารถเฉพาะที่แมปเข้ากับ OpenAI API ไม่ได้
1 ความคิดเห็น
ความเห็นจาก Hacker News
ฉันเป็น maintainer ของ LiteLLM ตอนนี้ยังอยู่ระหว่างการสืบสวน แต่จากที่ทราบจนถึงตอนนี้มีดังนี้
ขณะนี้กำลังวิเคราะห์สาเหตุและทบทวนมาตรการเสริมความปลอดภัย ต้องขออภัยในความไม่สะดวก
เรายัง เชื่อถือ dependencies และสภาพแวดล้อมการพัฒนา ไม่ได้อยู่ดี dev container มีการแยกที่ไม่เพียงพอและใช้งานไม่สะดวก ถึงเวลาต้องย้ายไปใช้ สภาพแวดล้อมการพัฒนาแบบ sandbox-based แล้ว ต้องมีการแยกระดับ VM, egress filter, seccomp และชั้นป้องกันอย่าง gVisor ถ้าเป็นสภาพแวดล้อมแบบนี้ ต่อให้เกิดการเจาะ ระบบก็จะปิดคอนเทนเนอร์ได้ทันทีและระบุปัญหาได้ง่าย
มีการแนะนำเครื่องมือ canary สำหรับ macOS (ลิงก์) เป็นไบนารี Go แบบง่าย ๆ ที่ใช้ตรวจจับไฟล์ที่แพ็กเกจไม่ควรเข้าถึง โดยเปิดเผยข้อมูลลับปลอมผ่าน WebDAV หรือ NFS และส่งการแจ้งเตือนเมื่อมีการเข้าถึง สามารถใช้ แนวทาง honeypot เพื่อตรวจจับพฤติกรรมผิดปกติได้
นี่เป็นเหตุการณ์ที่เกี่ยวข้องกับ กิจกรรมของ TeamPCP ในช่วงไม่กี่สัปดาห์ที่ผ่านมา ไทม์ไลน์ ที่ฉันสรุปไว้น่าจะช่วยได้
มีคนชี้ว่า ระบบตรวจจับสแปม ของ GitHub อ่อนแอเกินไป บอกว่าใน issue ของ litellm มีคอมเมนต์สแปมมากกว่า 170 รายการ
ฉันคาดไว้แล้วว่าสักวันเรื่องแบบนี้ต้องเกิดขึ้น เคยพยายามป้องกันด้วยการ ตรึงเวอร์ชันของ dependencies แต่ถึงอย่างนั้นก็ไม่สมบูรณ์ เพราะด้วย ความซับซ้อนของซัพพลายเชน ในโอเพนซอร์ส มันเป็นไปไม่ได้ที่จะตรวจสอบโค้ดทั้งหมด และด้วย LLM ความเสี่ยงที่มัลแวร์จะกระจายเป็นวงกว้างก็เพิ่มขึ้น 100 เท่า
ถ้าโค้ดที่ AI เขียนสามารถ แทรกซึมเข้า LLVM หรือ Linux ได้ เราก็คงต้องเผชิญกับปัญหา “trusting trust” อย่างแท้จริง
มีการพูดถึงข้อเท็จจริงที่ว่า หน่วยงานตรวจสอบ SOC2 ของ LiteLLM คือ Delve
มีคนบอกว่าพอติดตั้ง Harbor แล้ว CPU พุ่งไป 100% จนเครื่องค้าง โดยดูเหมือนว่าโปรเซส
grep -r rpcuser\rpcpasswordพยายาม ค้นหากระเป๋าคริปโต โชคดีที่ไม่มีการติดตั้ง backdoorเหตุการณ์ครั้งนี้ดูเหมือนเป็นฝีมือของ กลุ่มโจมตีเดียวกับ TeamPCP ที่แฮ็ก Trivy การที่ issue ถูกถล่มด้วยคอมเมนต์บอตก็เป็นแพตเทิร์นเดียวกัน จึงมีความเป็นไปได้สูงว่าเป็น การโจมตีอัตโนมัติที่ใช้ LLM