Skip to content

MCP Server Hardening:把 MCP 工具服务做稳做安全 ​

这篇文章解决什么问题 ​

MCP Server 让外部工具、资源和上下文更容易接入 Agent。但“能接入”不等于“能上线”。一个 MCP Server 如果没有 schema 约束、权限边界、超时控制、错误映射、审计日志和安全测试,就可能成为 Agent 系统里最危险的部分。

MCP Server Hardening 的目标是:把 MCP Server 从“能被模型调用的脚本”升级成“可授权、可限流、可审计、可测试、可降级的工具服务”。

MCP Server 风险地图 ​

风险示例
参数注入模型把恶意路径、SQL、命令拼进参数
权限绕过用户通过工具读取不属于自己的数据
数据泄漏工具返回过多字段、密钥、内部路径
危险副作用写文件、删数据、发通知、执行命令
Schema 漂移工具参数变了,Client 仍按旧 schema 调用
超时和资源耗尽工具卡住导致 Agent 任务阻塞
错误不可解释Server 抛异常,Agent 无法做恢复
供应链风险第三方工具更新后行为变化

这些风险不能只靠“模型会听话”解决,必须在 Server 侧做硬约束。

工具分级 ​

MCP Server 内每个工具都应该有风险等级。

等级示例默认策略
low读取公开配置、格式转换可自动执行
medium查询租户内数据、读取文档需要权限和审计
high写入业务状态、发送通知需要审批
critical删除、执行命令、生产变更多级审批或默认禁用

风险等级应该写进工具元数据,并被 MCP Client / Gateway 读取,用于权限过滤和审批策略。

输入参数校验 ​

不要相信模型生成的参数。

需要校验:

  • 必填字段是否存在。
  • 类型、枚举、长度、正则是否满足。
  • 路径是否在允许目录内。
  • URL 是否在允许域名内。
  • SQL 是否只读、是否带 tenant 过滤。
  • 数量、金额、时间范围是否超过阈值。
  • user_id、tenant_id 是否来自系统上下文,而不是模型参数。

特别注意:tenant_id、user_id、role 这类安全字段不应该让模型自由填写,应由服务端注入。

输出最小化 ​

工具返回给模型的内容越多,泄漏风险越高。

输出建议:

  • 默认只返回任务需要的字段。
  • 去掉密钥、token、内部路径、堆栈、原始 SQL。
  • 大文件返回摘要和引用 ID,不直接返回全文。
  • 错误信息做脱敏和分类。
  • 对敏感字段做 mask。

如果模型只需要“工单是否存在”,就不要返回完整客户资料。

超时、重试和取消 ​

MCP 工具必须有执行边界:

控制项建议
timeout每个工具配置最大执行时间
retry只对可重试错误重试
cancellationAgent 任务取消时能停止工具执行
concurrency按工具和租户限制并发
rate limit防止模型循环调用压垮外部系统
circuit breaker连续失败时暂停工具

没有超时的工具会拖垮整个 Agent Runtime。

错误映射 ​

MCP Server 不应该把原始异常直接抛给模型。建议统一错误结构:

字段说明
error_codePERMISSION_DENIED、INVALID_ARGS、TIMEOUT
retryable是否可重试
user_visible_message可以展示给用户的安全信息
developer_message给开发者看的脱敏诊断
trace_id关联后端日志
remediation建议下一步动作

这样 Agent 才能根据错误类型决定重试、改参数、请求审批、降级或转人工。

审计日志 ​

MCP Server 至少记录:

  • who:哪个用户、租户、Agent、run_id。
  • what:调用哪个 tool、schema version。
  • why:模型给出的调用理由或上游 step。
  • input:脱敏参数摘要和 hash。
  • output:结果状态、数量、摘要。
  • risk:风险等级、是否审批。
  • when:开始时间、结束时间、耗时。
  • result:成功、失败、被拦截、超时。

这些日志要和 Agent Trace 对齐,否则事故发生后很难复盘。

Schema 版本管理 ​

MCP 工具 schema 需要版本:

  • tool_name 不轻易变。
  • schema_version 显式记录。
  • 新增可选字段可以兼容。
  • 删除字段、改类型、改语义属于 breaking change。
  • Client / Gateway 做 schema diff。
  • 生产环境可 pin 某个 schema version。

如果 Server 更新 schema 后 Client 没有感知,模型可能继续按旧参数调用,导致错误或危险行为。

安全测试清单 ​

上线前至少测试:

  • invalid args 是否被拒绝。
  • 越权 tenant_id 是否被服务端覆盖或拒绝。
  • 路径穿越是否被拦截。
  • SSRF / 外部 URL 是否被 allowlist 限制。
  • Prompt Injection 诱导工具泄漏是否失败。
  • 高风险工具无审批是否不能执行。
  • 超时工具是否被取消。
  • Server 异常是否脱敏。
  • Schema diff 是否被发现。
  • 审计日志是否能还原一次调用。

面试表达模板 ​

我会把 MCP Server 当成生产工具服务来治理,而不是简单暴露函数。每个工具都有 schema version、risk_level、权限策略、timeout、rate limit 和审计日志。tenant_id、user_id 由服务端上下文注入,不信任模型参数。错误返回统一映射成可重试、不可重试、需审批、需人工接管等类型,并和 Agent Trace 关联。这样 MCP 接入后既能扩展工具生态,也不会放大安全风险。

常见误区 ​

误区一:MCP Server 能跑就算完成 ​

能跑只是第一步。能被安全调用、能审计、能降级才适合上线。

误区二:工具参数由模型生成,所以错了也是模型问题 ​

执行层必须校验参数。模型输出不是可信输入。

误区三:Server 只需要本地测试 ​

还要做 Client contract test、Gateway policy test、注入样本和 schema diff 测试。

相关链接 ​