把本地文件系统暴露给 MCP Server,本质上是把一部分文件访问权交给模型侧的工具调用链。风险不在于模型是否“听话”,而在于一旦工具描述、参数校验或路径解析出现缺口,越界访问就会变成可执行的文件操作。因此权限配置的目标不是功能最大化,而是把可访问范围压到刚好够用。
目录白名单:先定边界,再谈功能
最直接的控制手段是目录白名单。MCP Server 在启动时接收一组允许访问的根目录,所有文件操作都必须落在这些根目录之下。白名单的设计要点有三个:
第一,根目录应尽量具体。不要用用户主目录或整个磁盘根作为白名单,而是指向项目目录、数据目录这类明确的工作区。
第二,白名单在进程启动时固定,运行期不动态追加。动态追加意味着模型侧可以通过工具调用间接扩大自己的权限边界,这违背最小权限原则。
第三,白名单之外一律拒绝,而不是“默认允许、黑名单排除”。黑名单模式在文件系统场景下几乎必然漏项,因为路径形态太多。
读写权限边界:按工具粒度拆分
文件系统类工具通常包含读、写、列目录、删除等操作。权限边界不应只停留在“能不能访问这个目录”,而要细化到“能对这个目录做什么”。
一种可行做法是把读写权限拆成独立的配置项:读操作可以覆盖较大的目录范围,写操作只开放特定子目录。例如读取整个项目目录,但写入只允许落到 output/ 或 tmp/ 这类受控位置。删除操作则应默认关闭,确需开启时单独授权并限定目录。
这种拆分的好处是,即使模型侧发起了越界的写请求,也会在权限层被拦截,而不是依赖工具实现里的临时判断。
路径穿越防护:解析后再校验
路径穿越是文件系统类工具最典型的越界方式。../ 拼接、符号链接、绝对路径覆盖、URL 编码变体,都可能让一个看似合法的相对路径指向白名单之外。
防护的核心原则是:先做路径规范化,再做白名单校验,最后才执行文件操作。顺序不能颠倒。如果先校验字符串再解析路径,a/../../etc/passwd 这类输入就可能绕过检查。
具体来说,需要把用户传入的路径与白名单根目录拼接后,解析成规范化的绝对路径,然后判断该路径是否仍位于白名单根目录之下。同时要处理符号链接:如果白名单目录内存在指向外部的软链,仅靠字符串前缀判断会误放行。是否跟随符号链接,应在配置层明确,默认不跟随更安全。
进程级隔离:把风险关进沙箱
权限配置解决的是“工具层让不让做”,进程级隔离解决的是“即使工具层被绕过,能造成多大破坏”。
本地部署时,可以考虑用独立系统用户运行 MCP Server,该用户只对白名单目录有读写权限,对其他路径无权限。这样即使路径校验出现漏洞,操作系统层面的权限也会兜底。
容器化是另一种常见选择:把 MCP Server 放进容器,只挂载必要的目录,配合只读挂载和最小化的文件系统视图。容器内不暴露宿主机敏感路径,网络与进程能力也按需裁剪。
无论哪种方式,隔离的目标都是一致的:让 MCP Server 的文件访问能力不超过它真正需要的范围。
配置组织与可执行建议
配置层面,建议把白名单、读写权限、符号链接策略、是否允许删除等参数集中在一个配置文件里,而不是散落在代码或环境变量中。集中配置便于审计,也便于在不同环境间复制最小权限模板。
落地时可以按以下顺序推进:先确定工作区根目录,只开放读权限;确认工具调用正常后,再按需开放特定子目录的写权限;删除和符号链接跟随默认关闭;最后用独立用户或容器做进程级兜底。每一步都保持“默认拒绝、显式授权”的基调。
需要说明的是,以上属于工程实践层面的建议,具体配置项名称和实现方式取决于所用 MCP Server 的实际设计。在接入前,应以其官方文档和实际行为为准,逐项验证权限边界是否生效。