
6 Lỗ Hổng Bảo Mật MCP Server Thường Gặp Và Cách Vá Ngay
6 lỗ hổng MCP server lặp đi lặp lại — path traversal, RCE, deserialization, SSRF — kèm code fix copy-paste và checklist grep trước khi deploy cho agent nội bộ.
Bạn vừa dựng xong một MCP server cho agent nội bộ: nó đọc file, chạy lệnh, fetch URL theo yêu cầu của model. Vài tuần sau, một tài liệu độc hại lọt vào ngữ cảnh, và agent của bạn vô tình đọc /etc/passwd hoặc gọi lệnh shell do kẻ tấn công cài sẵn. Bài viết này liệt kê 6 lỗ hổng MCP server phổ biến nhất kèm code fix có thể copy-paste ngay, dựa trên một audit thực tế về MCP server và package AI/ML.
Vì sao MCP server là bề mặt tấn công mới
MCP (Model Context Protocol) server trao cho LLM các tool thật: đọc file, chạy lệnh, fetch URL. Vấn đề là tham số truyền vào các tool này lại đến từ nội dung không đáng tin — một trang web, một tài liệu, hay output của model khác. Đây là bề mặt injection kinh điển, và phần lớn MCP server đang mắc đúng 6 lỗ hổng lặp đi lặp lại.
1. Path traversal — đọc file tuỳ ý
Một tool read_file dùng open(base + user_path) sẽ lộ /etc/passwd ngay khi model được yêu cầu đọc ../../../../etc/passwd. Symlink và absolute path dễ dàng bypass các prefix check ngây thơ. Cách vá: resolve cả base lẫn target path, từ chối nếu target không nằm trong parents của base — không được "làm sạch" path rồi tiếp tục chạy, đó chính là cách lỗ hổng quay lại.
2. Command execution — RCE qua shell=True
Đoạn code kiểu subprocess.run(f"convert {name}", shell=True) là dấu chấm hết, vì bất kỳ tham số nào model can thiệp được đều coi như do kẻ tấn công kiểm soát. Fix: luôn truyền argv dạng list với shell=False, whitelist tham số người dùng thực sự được phép chỉnh, và từ chối mọi thứ ngoài danh sách đó.
3. Unsafe deserialization
pickle.load, torch.load bản trước 2.6 (mặc định không an toàn), yaml.load không dùng safe loader, và numpy.load(allow_pickle=True) đều có thể thực thi code ngay khi load. Đây được ghi nhận là nhóm lỗi được trả thưởng nhiều nhất trên huntr cho MCP/AI. Dùng yaml.safe_load, torch.load(f, weights_only=True), và ưu tiên định dạng safetensors thay vì pickle cho model.
4. SSRF trong tool fetch URL
Một tool fetch_url sẵn sàng gọi tới http://169.254.169.254/ (cloud metadata) hoặc http://localhost:6379 nếu không kiểm soát. Trước khi connect, resolve hostname và chặn toàn bộ private range, đồng thời tắt redirect và giới hạn kích thước response.
Checklist chạy trước mỗi lần deploy
Grep nhanh trong source trước khi release: tìm shell=True, os.system, subprocess.call(; tìm pickle.load, yaml.load(, torch.load(, allow_pickle=True; tìm open(, Path(, send_file, extractall. Sau đó bắn thử các payload tấn công thật — ../, 169.254.169.254, một pickle chứa __reduce__ — vào instance local và xác nhận từng cái đều bị từ chối.
Việc cần làm tiếp theo
Nếu team bạn đang build MCP server cho agent nội bộ, chạy ngay bộ grep checklist ở trên trên codebase hiện tại trước khi nghĩ đến tính năng mới. Đừng đợi security review hàng quý — mỗi tool mới thêm vào agent là một bề mặt tấn công mới cần soi qua đúng 6 nhóm lỗi này.
Không spam, hủy đăng ký bất kỳ lúc nào.


