ความปลอดภัยของ MCP: สิ่งที่ผมได้เรียนรู้หลังจากระบบล่มในโปรดักชันถึง 95 ครั้ง

ผมเคยคิดว่าความปลอดภัยเป็นเรื่องง่าย แค่อัปเดต dependencies ใช้ HTTPS และไม่เขียน secrets ลงในโค้ดโดยตรง

ผมคิดผิด

หลังจากระบบล่มในโปรดักชันถึง 95 ครั้ง และใช้เวลาพัฒนาไปกว่า 1,800 ชั่วโมง ผมได้เรียนรู้ว่าความปลอดภัยของ Model Context Protocol (MCP) นั้นแตกต่างออกไป มันไม่เหมือนกับความปลอดภัยของ REST API มาตรฐาน

MCP สร้างความเสี่ยงใหม่ๆ เพราะ client คือ LLM ไม่ใช่คน

และนี่คือสิ่งที่คุณต้องรู้เพื่อรักษาความปลอดภัยให้กับ MCP server ของคุณ

  1. โมเดลภัยคุกคามของ MCP (The MCP Threat Model)

ใน REST คุณจะรู้แน่ชัดว่าใครเป็นคนเรียก API ของคุณ แต่ใน MCP นั้น LLM จะทำหน้าที่เป็นตัวกลาง ซึ่งสิ่งนี้เปลี่ยนทุกอย่าง:

  • LLM สามารถเกิดอาการ "หลอน" (hallucinate) ในการเรียกใช้ tool หรือพารามิเตอร์ได้
  • ผู้ใช้ไม่ได้เรียกใช้ tool โดยตรง แต่พวกเขาคุยกับ LLM และ LLM จะเป็นคนคุยกับ server ของคุณ
  • client ที่ประสงค์ร้ายสามารถตรวจสอบ server ของคุณเพื่อค้นหา tool ที่ซ่อนอยู่ระหว่างขั้นตอนการทำ discovery ได้

ภัยคุกคามที่ใหญ่ที่สุดของคุณไม่ใช่แค่แฮกเกอร์ แต่คือ LLM ที่หวังดีแต่ดันทำผิดพลาดโดยไม่ตั้งใจจนทำให้ระบบของคุณล่ม

  1. การจัดการ API Key

นักพัฒนาหลายคนส่ง API key ผ่าน query parameters เพื่อความสะดวก แต่นี่คือข้อผิดพลาด เพราะ query parameters จะปรากฏอยู่ในทุก server log และ proxy

ปฏิบัติตามกฎเหล่านี้:

  • ใช้การยืนยันตัวตนผ่าน header (Authorization: Bearer)
  • หลีกเลี่ยงการส่ง key ใน JSON body
  • ออก API key แยกกันสำหรับแต่ละ client วิธีนี้จะช่วยให้คุณติดตามการใช้งานและยกเลิกสิทธิ์การเข้าถึงได้โดยไม่กระทบกับส่วนอื่นๆ ทั้งหมด
  1. การตรวจสอบข้อมูลขาเข้าอย่างเข้มงวด (Strict Input Validation)

LLM มักจะเดาผิด พวกมันอาจส่งข้อมูลผิดประเภทหรือส่งพารามิเตอร์ส่วนเกินมา คุณต้องตรวจสอบทุกการเรียกใช้งาน:

  • ตรวจสอบก่อนว่าชื่อ tool มีอยู่ในรายการของคุณหรือไม่
  • ปฏิเสธการเรียกที่มีพารามิเตอร์ส่วนเกิน อย่าแค่เพิกเฉยต่อมัน
  • ตรวจสอบประเภทของพารามิเตอร์ให้ตรงกันอย่างแม่นยำ อย่าทำการแปลงประเภทข้อมูล (coerce data types) เอง
  • กำหนดขีดจำกัดขนาดของ string และ array อย่างเข้มงวดเพื่อป้องกันปัญหาหน่วยความจำเต็มจนระบบล่ม
  • ทำความสะอาด (sanitize) path ของไฟล์ทั้งหมดเพื่อป้องกันการโจมตีแบบ directory traversal
  1. การจำกัดอัตราการเรียกใช้งานแบบเป็นชั้น (Layered Rate Limiting)

prompt เดียวจากผู้ใช้สามารถกระตุ้นให้เกิดการเรียกใช้ tool พร้อมกันถึงสิบครั้ง ซึ่งอาจทำให้ connection pool ของคุณหมดลงภายในไม่กี่วินาที

ใช้การป้องกันสามชั้น:

  • จำกัดการใช้งานต่อ API key เพื่อควบคุมการใช้งานของ client
  • จำกัดการใช้งานต่อ IP เพื่อหยุดการโจมตีแบบ brute force
  • จำกัดการเชื่อมต่อที่เกิดขึ้นพร้อมกัน (concurrent connection limits) เพื่อให้ server ยังทำงานได้ในช่วงที่มีการใช้งานพุ่งสูงขึ้นอย่างรวดเร็ว
  1. ความเสี่ยงจากการทำ Prompt Injection

ผู้ใช้สามารถหลอกล่อ LLM ให้เรียกใช้ tool ที่สร้างความเสียหายได้ เช่น ถ้าผู้ใช้สั่งให้ LLM ลบโน้ตทั้งหมด LLM ก็อาจจะทำตามนั้นจริงๆ

วิธีป้องกันตัวเอง:

  • แยกการทำงานระหว่างการอ่าน (read) และการเขียน (write) ออกจากกัน
  • กำหนดให้ต้องมีการยืนยันจากผู้ใช้ด้วยตนเองสำหรับการลบหรืออัปเดตข้อมูลใดๆ
  • ใช้หลักการสิทธิ์ขั้นต่ำที่จำเป็น (principle of least privilege) สำหรับ user ของฐานข้อมูล

ความปลอดภัยเป็นกระบวนการที่ต้องทำอย่างต่อเนื่อง เริ่มต้นด้วยการจัดการ key ที่ดีขึ้นและการตรวจสอบข้อมูลที่เข้มงวด ขั้นตอนเหล่านี้จะช่วยแก้ปัญหาได้ส่วนใหญ่

Source: https://dev.to/kevinten10/mcp-security-what-i-learned-securing-my-mcp-server-after-95-production-outages-3hc0

Optional learning community: https://t.me/GyaanSetuAi