Bảo mật MCP: Những gì tôi đã học được sau 95 lần sập hệ thống thực tế

Tôi từng nghĩ bảo mật thật đơn giản. Cập nhật các phụ thuộc (dependencies). Sử dụng HTTPS. Không mã hóa cứng (hardcode) các thông tin bí mật.

Tôi đã lầm.

Sau 95 lần sập hệ thống thực tế và 1.800 giờ phát triển, tôi nhận ra rằng bảo mật Model Context Protocol (MCP) rất khác biệt. Nó không giống như bảo mật REST API tiêu chuẩn.

MCP tạo ra những rủi ro mới vì client là một LLM, chứ không phải con người.

Dưới đây là những điều bạn phải biết để giữ cho máy chủ MCP của mình an toàn.

  1. Mô hình đe dọa MCP (The MCP Threat Model)

Trong REST, bạn biết chính xác ai đang gọi API của mình. Trong MCP, LLM đóng vai trò là trung gian. Điều này thay đổi mọi thứ:

  • LLM có thể "ảo giác" (hallucinate) về các lời gọi công cụ (tool calls) hoặc tham số.
  • Người dùng không gọi trực tiếp các công cụ. Họ trò chuyện với LLM, và LLM sẽ trò chuyện với máy chủ của bạn.
  • Các client độc hại có thể dò tìm các công cụ ẩn trên máy chủ của bạn trong quá trình khám phá (discovery).

Mối đe dọa lớn nhất của bạn không chỉ là hacker. Đó còn là một LLM có ý định tốt nhưng lại vô tình mắc lỗi khiến hệ thống của bạn bị sập.

  1. Quản lý API Key

Nhiều lập trình viên truyền API key qua các tham số truy vấn (query parameters) để cho tiện. Đây là một sai lầm. Các tham số truy vấn sẽ xuất hiện trong mọi nhật ký (log) máy chủ và proxy.

Hãy tuân thủ các quy tắc sau:

  • Sử dụng xác thực qua header (Authorization: Bearer).
  • Tránh truyền key trong thân (body) JSON.
  • Cấp một API key khác nhau cho mỗi client. Điều này giúp bạn theo dõi mức độ sử dụng và thu hồi quyền truy cập mà không làm hỏng toàn bộ hệ thống.
  1. Xác thực đầu vào nghiêm ngặt (Strict Input Validation)

LLM sẽ đoán sai. Chúng sẽ gửi sai kiểu dữ liệu và các tham số thừa. Bạn phải xác thực mọi lời gọi:

  • Trước tiên, hãy kiểm tra xem tên công cụ có tồn tại trong danh sách của bạn hay không.
  • Từ chối các lời gọi có tham số thừa. Đừng chỉ đơn giản là bỏ qua chúng.
  • Khớp chính xác các kiểu tham số. Đừng ép kiểu dữ liệu (coerce data types).
  • Thiết lập giới hạn kích thước nghiêm ngặt cho chuỗi (strings) và mảng (arrays) để ngăn chặn việc tràn bộ nhớ gây sập hệ thống.
  • Làm sạch (sanitize) tất cả các đường dẫn tệp để ngăn chặn tấn công duyệt thư mục (directory traversal).
  1. Giới hạn tốc độ theo lớp (Layered Rate Limiting)

Một câu lệnh (prompt) của người dùng có thể kích hoạt mười lời gọi công cụ cùng một lúc. Điều này có thể làm cạn kiệt pool kết nối của bạn chỉ trong vài giây.

Sử dụng ba lớp phòng thủ:

  • Giới hạn theo từng API key để kiểm soát mức độ sử dụng của client.
  • Giới hạn theo từng IP để ngăn chặn các cuộc tấn công brute force.
  • Giới hạn kết nối đồng thời để giữ cho máy chủ của bạn hoạt động ổn định trong các đợt truy cập tăng đột biến.
  1. Rủi ro Prompt Injection

Một người dùng có thể lừa LLM gọi một công cụ có tính phá hủy. Nếu người dùng bảo LLM xóa tất cả ghi chú, LLM có thể thực sự làm điều đó.

Hãy tự bảo vệ mình:

  • Tách biệt các thao tác đọc và ghi.
  • Yêu cầu người dùng xác nhận thủ công cho bất kỳ hành động xóa hoặc cập nhật nào.
  • Sử dụng nguyên tắc đặc quyền tối thiểu (principle of least privilege) cho người dùng cơ sở dữ liệu của bạn.

Bảo mật là một quá trình liên tục. Hãy bắt đầu với việc quản lý key tốt hơn và xác thực nghiêm ngặt. Những bước này sẽ giải quyết được hầu hết các vấn đề.

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