我们构建了MCP一直需要的安全防护层
保护LLM的上下文窗口
在进行"越线攻击"时,恶意MCP服务器会在工具描述、服务器指令或其他告诉模型如何与服务器交互的字段中包含提示注入有效载荷。通过这种技术,攻击者可以在任何恶意工具被调用之前操纵模型的行为,绕过MCP内置的人工干预控制。换句话说,越线攻击不依赖于让模型调用恶意工具;它直接攻击模型的上下文窗口,即使恶意服务器的工具从未被调用。
这一观察对我们如何防御这些攻击具有重要意义。安全控制应部署在风险实现的信任边界处,在我们研究的攻击中,风险存在于MCP服务器的描述和模型的上下文窗口之间。因此,应该有一个安全控制,使恶意MCP服务器更难通过工具描述将有害文本注入上下文窗口。
为兼容性和可靠性设计mcp-context-protector包装服务器
我们将mcp-context-protector构建为一个直接安装到LLM应用中的包装器,充当应用和下游服务器之间的代理。
图1:mcp-context-protector架构
这是我们保护LLM上下文窗口的首选解决方案。通过位于LLM和下游服务器之间,包装器可以在每条消息进入上下文窗口之前对其执行安全检查。
其他方法,如使用外部代码扫描器,无法提供相同的保护。像Invariant Labs的mcp-scan检查模式这样的配置扫描器可能会在MCP服务器的第一个安装版本中检测到提示注入攻击或其他恶意迹象,但不会检测到软件更新后出现的任何攻击。对所有更新强制执行代码扫描和手动批准将是一项艰巨的任务,特别是因为MCP服务器可以通过任何包管理工具下载和更新。另一个选择是依赖商业托管的服务器注册表,并相信注册表的审查过程将确保没有危险工具可供下载,但这些注册表如何审查代码或寻找什么攻击没有标准化(甚至常规)流程。
通过在LLM应用和不受信任的MCP服务器之间放置安全工具,可以在任何潜在危险内容呈现给模型之前检查每个通信的潜在问题。除了是最可靠的安全架构外,这种方法还确保了普遍兼容性。由于mcp-context-protector通过与每个MCP服务器相同的协议进行通信,任何使用MCP的应用都可以使用mcp-context-protector,无需修改或额外插件。
包装器与SDK更新及扩展工具定义接口的比较
在我们构建mcp-context-protector时,一个独立的工程师团队正在开发扩展工具定义接口(ETDI),这是对MCP规范和SDK的修订,解决了与mcp-context-protector相同的一些问题。但虽然它们的目标非常相似,这两种工具使用截然不同的方法来实现这些目标。mcp-context-protector设计用于普遍兼容性和易于安装,而正确实现ETDI需要LLM应用和MCP服务器的开发者和分发者更新其工作流程。
mcp-context-protector的安全功能
首次使用信任服务器固定
如前一节所述,基于工具的提示注入攻击不仅可能在服务器安装时实现,还可能在其配置更改时(如软件更新后)实现。这对于托管在远程基础设施上的基于HTTP的MCP服务器以及通过stdio传输运行的本地服务器都适用。为解决这一风险,mcp-context-protector使用首次使用信任系统,要求用户手动审查和批准下游服务器工具配置的更改。
当首次安装新服务器时,mcp-context-protector将其配置视为不受信任并阻止其所有功能。无法调用任何工具,工具描述甚至不会从下游服务器转发到LLM应用。要启用服务器,用户必须使用mcp-context-protector的命令行界面审查服务器的配置,包括其服务器指令、工具描述和工具参数描述。
当用户完成此过程并确认信任服务器后,mcp-context-protector将在其本地数据库中保存服务器配置。下次LLM应用打开时,下游服务器将被识别,用户将完全访问其工具和其他功能。
如果下游服务器的配置发生更改,例如添加新工具、更改工具描述或更改服务器指令,每个修改的字段都是新的潜在提示注入向量。因此,当mcp-context-protector检测到配置更改时,它会阻止访问用户未手动预先批准的任何功能。
LLM护栏扫描工具响应
针对提示注入对LLM应用构成的近乎普遍威胁,近年来发表了大量关于检测提示注入的研究,产生了LLM护栏系统和工具包,如Meta新发布的LlamaFirewall和NVIDIA的NeMo Guardrails。mcp-context-protector为用户提供选项,让他们选择的护栏框架自动扫描所有工具响应。如果选择的护栏框架确定下游MCP服务器的响应包含提示注入攻击或其他不安全内容,响应将被放入隔离区,LLM应用将收到解释性错误消息。
图2:护栏警报后响应被隔离
用户然后可以启动mcp-context-protector作为CLI应用来审查被隔离的响应。如果用户确认护栏警报是误报,他们可以将响应标记为安全释放。然后LLM应用可以使用包装器服务器的quarantine_release工具从隔离区检索原始响应并继续工作。
图3:用户确认隔离响应安全,然后释放给LLM应用
清理ANSI控制序列
正如我们最近关于MCP的帖子所讨论的,ANSI控制字符可用于隐藏提示注入攻击,并混淆在终端中显示的恶意输出。Claude Code和其他基于shell的LLM应用的用户可以打开mcp-context-protector的ANSI控制字符清理功能。此功能不是剥离ANSI控制序列,而是将转义字符(十六进制值为1b的字节)替换为ASCII字符串ESC。这样,输出被渲染为无害但可见。
当用户通过CLI应用审查服务器配置时,此功能会自动打开:
图4:服务器配置审查期间ANSI控制字符可见渲染
思维链审计的限制
使用MCP本身将mcp-context-protector插入LLM应用和MCP服务器之间有一个明显的缺点:mcp-context-protector无法完全访问对话历史,因此无法在决定工具调用是否安全或符合用户意图时使用这些数据。执行 exactly 那种分析的AI护栏示例是集成到LlamaFirewall中的AlignmentCheck。AlignmentCheck使用微调模型评估代理工作流的整个消息历史,寻找代理偏离用户陈述目标的迹象。如果检测到错位,工作流可以被中止。
由于mcp-context-protector本身是一个MCP服务器,按设计,它缺乏全面评估整个思维链所需的信息,并且无法利用AlignmentCheck。
手动配置审查和警报疲劳
这种方法的第二个限制在于手动审查过程本身及其可能给人工干预带来的负担。在某些环境中,MCP服务器可能频繁更改其配置。例如,发布提供访问大型复杂API的MCP服务器的供应商可能在其API每次更改时更新其MCP服务器。随着时间的推移,警报疲劳会产生影响,用户可能错过恶意行为的迹象(或者更糟,完全停止使用MCP安全控制)。因此,如果MCP服务器更新频繁,组织应考虑由安全工程师进行集中审查,而不是依赖个别用户使用mcp-context-protector等工具保护自己的部署。
在组织中采用mcp-context-protector
由于mcp-context-protector本身是一个符合标准的MCP服务器,它可以与任何主机应用和任何下游服务器一起使用。理想情况下,它应该用于安装在任何类型应用中的每个MCP服务器,包括通用聊天机器人、AI辅助代码编辑器和其他代理。
当前在mcp-context-protector中实现的安全控制只是开始;开发者可以添加任何适合组织使用场景的控制类型。示例可能包括数据丢失预防检查或对从网络检索的数据的额外护栏。