นักวิจัยด้านความปลอดภัยที่สแกนโปรเจกต์ MCP (Model-Control-Protocol) server แบบโอเพนซอร์สจำนวน 24 โปรเจกต์ ได้ค้นพบช่องโหว่การฉีดคำสั่งใน sandbox (sandbox command-injection) ที่รุนแรงเพียงหนึ่งเดียว ซึ่งมีคะแนนสูงถึง 9.8 บนมาตรวัด CVSS บั๊กนี้อยู่ใน AgenticX ซึ่งเป็นเฟรมเวิร์ก AI-agent ระดับกลาง และช่วยให้ผู้โจมตีสามารถฉีดคำสั่ง shell ใดๆ เข้าไปยัง Docker container ที่รันเซิร์ฟเวอร์ได้

ทำไม MCP server ถึงมีความสำคัญ

MCP คือตัวเชื่อมที่ช่วยให้ AI agent แบบอัตโนมัติสามารถสื่อสารกับเครื่องมือภายนอกได้ เช่น ไฟล์, ฐานข้อมูล, เบราว์เซอร์ และอื่นๆ นักพัฒนาจะฝัง MCP server ไว้ในแอปพลิเคชันของตนเพื่อให้โมเดลภาษา (language model) มีความสามารถในการอ่าน เขียน และดำเนินการกับทรัพยากรในโลกแห่งความเป็นจริง ตัวโปรโตคอลเองนั้นมีน้ำหนักเบาและได้รับการยอมรับอย่างแพร่หลาย แต่ผู้ดูแลโปรเจกต์แต่ละรายต้องรับผิดชอบในการรักษาความปลอดภัยของโค้ดที่อยู่ล้อมรอบ

การใช้งาน MCP ขนาดใหญ่ เช่น Cline หรือ Aider ได้รับการตรวจสอบ (audit) อย่างสม่ำเสมอและมีกระบวนการรักษาความปลอดภัยที่เข้มงวดแล้ว ส่วนโปรเจกต์ทั้ง 24 แห่งที่ตรวจสอบในที่นี้อยู่ในระดับ "mid-tier" บน GitHub โดยมีจำนวนดาวระหว่าง 100 ถึง 1,000 ดวง เรโพสิทอรี (repositories) เหล่านั้นมักให้ความสำคัญกับการส่งมอบฟีเจอร์ที่รวดเร็วมากกว่าการเขียนโค้ดให้มีความปลอดภัยสูง (hardened code) ซึ่งสร้างจุดบอดสำหรับผู้ใช้ที่ทึกทักเอาเองว่า MCP server แบบโอเพนซอร์สทุกตัวนั้นปลอดภัยโดยพื้นฐาน

การสแกน

นักวิจัยได้สร้างเครื่องมือสแกนเพื่อค้นหารูปแบบการโจมตีเว็บแอปพลิเคชันแบบคลาสสิก 5 รูปแบบ:

  • Command injection
  • Path traversal
  • Server-Side Request Forgery (SSRF)
  • SQL injection
  • Sandbox escape

การรันเครื่องมือสแกนผ่านไฟล์ซอร์สโค้ด 5,911 ไฟล์ ทำให้พบการแจ้งเตือนเบื้องต้น 94 รายการ หลังจากผ่านการคัดกรองด้วยตนเอง (manual triage) พบว่ามีเพียงรายการเดียวเท่านั้นที่เป็นช่องโหว่ที่แท้จริง

เจาะลึกบั๊กใน AgenticX

AgenticX สร้างคำสั่ง shell โดยการนำสตริงที่ผู้ใช้ป้อนมาแทรก (interpolate) ลงใน Python f-strings จากนั้นจึงส่งผลลัพธ์ไปยัง shell ของ container โดยตรง โดยไม่มีการตรวจสอบ (validation) หรือการใส่เครื่องหมายคำพูด (quoting) ให้กับเส้นทางไฟล์ (file paths) ดังนั้น prompt ที่เป็นอันตรายจึงสามารถฉีดเครื่องหมาย semicolon หรืออักขระพิเศษอื่นๆ ของ shell เข้าไปได้ ซึ่งจะทำให้ container รันคำสั่งใดๆ ก็ตามที่ผู้โจมตีเลือก

นักวิจัยได้แก้ไขโค้ดโดย:

  1. ใช้ shlex.quote() เพื่อ escape เส้นทางใดๆ ที่ส่งมาจาก language model อย่างปลอดภัย
  2. เพิ่มการตรวจสอบรูปแบบ path-traversal (../) อย่างชัดเจนก่อนที่จะสร้างคำสั่ง

การรันเครื่องมือสแกนอีกครั้งหลังการแก้ไขแสดงให้เห็นว่าระดับความเสี่ยงลดลงอย่างมาก ซึ่งยืนยันว่าการแก้ไขนี้สามารถจัดการกับต้นเหตุของปัญหาได้

ใครได้ ใครเสีย

  • นักพัฒนา AI ที่ฝัง MCP server ไว้ในผลิตภัณฑ์ของตน ตอนนี้มีตัวอย่างที่เป็นรูปธรรมว่าขั้นตอนการทำ sanitization ที่ขาดหายไปเพียงขั้นตอนเดียวสามารถทำลายห่วงโซ่ความปลอดภัยทั้งหมดได้อย่างไร จงปฏิบัติกับทุกพารามิเตอร์ที่มาจาก language model เสมือนว่าเป็นข้อมูลที่ไม่น่าเชื่อถือ (untrusted input) เช่นเดียวกับที่คุณทำกับ payload ของ API ภายนอกใดๆ

อีกด้านหนึ่งของเรื่องราว

นักวิจัยเน้นย้ำว่าตัวโปรโตคอล MCP เองยังคงมีความปลอดภัย ช่องโหว่นี้ไม่ใช่จุดอ่อนในการออกแบบรูปแบบการรับส่งข้อมูล (wire format) แต่เป็นความผิดพลาดในการเขียนโค้ดของการนำไปใช้งานเฉพาะเจาะจง โปรเจกต์ขนาดใหญ่ที่มีการตรวจสอบอย่างดีได้แก้ไขปัญหาที่คล้ายกันไปแล้ว และชุมชนโอเพนซอร์สสามารถเรียนรู้จากการแก้ไขบั๊กของ AgenticX ได้ อย่างไรก็ตาม เหตุการณ์นี้แสดงให้เห็นว่าโปรเจกต์ระดับ "mid-tier" สามารถมีบั๊กที่ส่งผลกระทบสูงได้ แม้จะมีจำนวนดาวไม่มากนักก็ตาม

บทสรุป

f-string เพียงตัวเดียวที่ไม่ได้ตรวจสอบใน AgenticX เปลี่ยน MCP server ทั้งหมดให้กลายเป็นฐานปล่อยสำหรับการรันโค้ดตามอำเภอใจ (arbitrary code execution) เหตุการณ์นี้พิสูจน์ให้เห็นว่าความปลอดภัยของระบบนิเวศ AI-agent ขึ้นอยู่กับการนำไปใช้งานอย่างมีวินัยมากกว่าตัวโปรโตคอล นักพัฒนาต้องปฏิบัติกับทุกพารามิเตอร์ที่สร้างโดย LLM เสมือนว่าเป็นอันตราย แพลตฟอร์มควรบังคับใช้มาตรการป้องกันในขณะรันไทม์ (runtime safeguards) และเครื่องมือด้านความปลอดภัยจำเป็นต้องพัฒนาเพื่อทำความเข้าใจห่วงโซ่ความเชื่อถือ (trust chains) ที่เป็นเอกลักษณ์ซึ่ง AI agent สร้างขึ้น

ที่มา: dev.to/easterndev/i-scanned-24-mcp-server-projects-and-found-a-real-sandbox-command-injection-cvss-98-4k9h