返回博客

MCP 工具接入前如何限制文件和命令权限

人工智能4613
MCP 工具接入前如何限制文件和命令权限

把文件、数据库或命令封装成 MCP 工具后,模型获得的不只是更多上下文,也可能获得修改系统状态的入口。风险并不取决于工具名称是否友好:名为 read_file 的工具可能接受任意路径,名为 run_test 的工具也可能把参数直接拼进 Shell。接入前应把每个工具当作外部调用接口审查,明确输入边界、运行身份、可观察副作用和失败策略。本文给出一份不依赖具体 SDK 版本的检查方法,适合本地或远程 MCP Server 的设计评审。

从一张工具清单开始

对每个 Server 列出实际暴露的能力:

字段需要记录的内容
工具名客户端可见的稳定标识
输入字段、类型、长度和允许值
读取范围文件、数据库、网络或应用对象
写入范围会创建、修改或删除什么
运行身份使用哪个系统账号或服务凭据
外部影响是否发送消息、执行命令或改变远端状态
审批要求哪些参数组合必须人工确认
审计字段如何关联用户、任务和结果

只写“文件工具”或“Git 工具”不足以评估风险。读取仓库状态和推送远端分支属于完全不同的权限等级,应拆成不同工具。

文件工具必须先归一化路径

仅检查字符串是否以允许目录开头并不可靠。相对路径、.. 和符号链接都可能越过预期边界。实现层应先把用户输入解析为规范路径,再确认它位于明确的根目录内。

下面的 Python 示例只演示路径边界检查:

python
from pathlib import Path

WORKSPACE = Path("workspace").resolve()

def resolve_workspace_path(raw_path: str) -> Path:
    candidate = (WORKSPACE / raw_path).resolve()
    if not candidate.is_relative_to(WORKSPACE):
        raise ValueError("path is outside workspace")
    return candidate

调用方仍需分别处理文件是否存在、符号链接策略、允许扩展名和单文件大小。写入工具还应默认拒绝覆盖,并使用独立输出目录。

读和写不要共用一个万能工具

把能力拆成最小动作:

text
list_files:列出允许目录中的条目
read_file:读取允许类型的单个文件
create_output:只在输出目录创建新文件
replace_output:修改已生成的产物,需要差异预览
delete_output:单独授权,默认关闭

拆分后,客户端可以只启用当前任务需要的集合。若一个 file_tool 同时支持读取任意文件、覆盖和删除,就无法针对高风险动作设置独立审批。

命令工具使用参数数组和白名单

不要提供接受任意 Shell 字符串的 run_command。优先为具体任务定义工具,例如运行目标测试或读取版本信息,并将可选参数限制为枚举或经过验证的路径。

实现命令调用时使用参数数组,不通过 Shell 解释用户输入:

python
import subprocess

def run_target_test(test_path: str) -> subprocess.CompletedProcess[str]:
    path = resolve_workspace_path(test_path)
    if path.suffix != ".py":
        raise ValueError("only Python test files are allowed")
    return subprocess.run(
        ["python", "-m", "pytest", "-q", str(path)],
        cwd=WORKSPACE,
        text=True,
        capture_output=True,
        timeout=120,
        check=False,
    )

超时时间、输出上限和子进程环境需要按实际服务设置。示例不能替代操作系统级隔离,也不表示所有仓库都应允许模型执行测试。

数据库工具优先只读和参数化查询

如果任务只需分析数据,使用只读账号连接只读副本,并将查询范围限制在允许的表或预定义操作。不要让模型提交任意 SQL 后再依靠提示词禁止写入。

确需修改数据时,把读取、生成变更计划和执行变更拆成不同阶段。执行前展示目标记录、预期差异和回滚标识,由业务权限系统批准。

远程 Server 需要独立身份

远程部署时,客户端身份、Server 进程身份和后端资源凭据应分开。一个请求至少需要能够关联:

text
谁发起调用
属于哪个任务或会话
调用了哪个工具
使用了哪些非敏感参数摘要
返回什么状态
是否产生外部写入
由谁批准

日志不应默认记录完整文件内容、数据库结果、提示词和认证凭据。身份验证成功也不代表有权调用所有工具,授权应在 Server 侧按工具和资源继续判断。

防止错误重试扩大副作用

只读操作可以在有限条件下重试,写入操作则要有幂等标识和状态查询。若客户端超时,Server 应能判断同一操作是否已经完成,而不是再次执行。

对删除、推送、发送和审批等动作,默认要求人工确认。确认信息必须包含具体目标和参数摘要,不能只显示“允许工具调用”。

用负面测试验证边界

接入测试不能只验证正常请求。至少覆盖:

每个拒绝结果都应有稳定的错误类别,客户端才能停止或请求人工处理,而不是盲目换一种参数继续尝试。

结论与限制

MCP 工具的安全边界来自 Server 实现和运行环境,而不是工具描述或系统提示词。先建立工具清单,再落实规范路径、读写分离、参数白名单、最小身份和负面测试,可以减少模型调用越过任务范围的机会。

本文不覆盖某一 MCP SDK 的具体接口、传输认证或部署配置。协议与 SDK 会变化,实施时应依据所用版本的官方规范核对消息格式和能力;高风险 Server 仍需要代码审计、依赖检查与操作系统级隔离。

标签:MCPAI Agent安全设计

推荐阅读

探索更多前沿洞察与行业干货。