我们构建了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,而无需修改或额外插件。
通过这种方式,mcp-context-protector服务于与mcp-scan代理模式类似的目的。一个区别是mcp-scan的代理要求用户启动一个单独的进程,而mcp-context-protector是"设置即忘记"。一旦MCP客户端配置为通过包装器连接到服务器,mcp-context-protector将永久就位。
包装器与SDK更新和扩展工具定义接口
在我们构建mcp-context-protector的同时,一个独立的工程师团队正在开发扩展工具定义接口(ETDI),这是对MCP规范和SDK的修订,解决了与mcp-context-protector相同的一些问题。但尽管他们的目标非常相似,这两种工具使用 vastly不同的方法来实现这些目标。mcp-context-protector设计用于通用兼容性和易于安装,而正确实施ETDI要求LLM应用和MCP服务器的开发人员和分发者更新他们的工作流程。例如,ETDI使用OAuth签名来确保服务器配置的一致性和真实性,这需要密钥管理基础设施,而今天的MCP服务器不需要。
我们鼓励您阅读ETDI论文并关注Python SDK的ETDI实现开发。如果在生态系统中广泛采用,ETDI可能代表对MCP一些安全问题的健壮和可持续解决方案。目前,mcp-context-protector可以在轻量级、通用兼容的包装器中提供类似的安全保证,无需对MCP服务器或LLM应用进行任何更改。
mcp-context-protector的安全功能
首次使用信任服务器固定
如前一节所述,基于工具的提示注入攻击不仅可以在服务器安装时实现,还可以在其配置更改时实现,例如软件更新后。这对于托管在远程基础设施上的基于HTTP的MCP服务器以及通过stdio传输运行的本地服务器都是如此。为了解决这种风险,mcp-context-protector使用首次使用信任系统,要求用户手动审查和批准下游服务器工具配置的更改。
当首次安装新服务器时,mcp-context-protector将其配置视为不受信任并阻止其所有功能。无法调用任何工具,工具描述甚至不会从下游服务器转发到LLM应用。要启用服务器,用户必须使用mcp-context-protector的命令行界面审查服务器的配置,包括其服务器指令、工具描述和工具参数描述。
当用户完成此过程并确认他们信任服务器时,mcp-context-protector将将服务器配置保存到其本地数据库中。下次LLM应用打开时,下游服务器将被识别,用户将完全访问其工具和其他功能。
如果下游服务器的配置 ever更改,例如添加新工具、更改工具描述或更改服务器指令,每个修改的字段都是新的潜在提示注入向量。因此,当mcp-context-protector检测到配置更改时,它会阻止访问用户未手动预先批准的任何功能。具体来说,如果引入了新工具,或者工具的描述或参数已更改,则该工具被阻止,永远不会发送到下游LLM应用。如果服务器的指令更改,整个服务器被阻止。这样,MCP服务器配置更改不可能在没有手动批准步骤的情况下将新文本(因此,新的提示注入攻击)引入LLM的上下文窗口。
LLM护栏扫描工具响应
针对提示注入对LLM应用构成的几乎普遍威胁,近年来发表了大量关于检测提示注入的研究,导致了LLM护栏系统和工具包,如Meta新发布的LlamaFirewall和NVIDIA的NeMo Guardrails。mcp-context-protector为用户提供了选项,让他们选择的护栏框架自动扫描所有工具响应。如果选择的护栏框架得出结论,下游MCP服务器的响应包含提示注入攻击或其他不安全内容,响应将被置于隔离区,LLM应用将收到解释性错误消息。
图2:护栏警报后响应被隔离
然后用户可以启动mcp-context-protector作为CLI应用来审查隔离的响应。如果用户确认护栏警报是误报,他们可以将响应标记为安全释放。然后LLM应用可以使用包装器服务器的quarantine_release工具从隔离区检索原始响应并继续工作。
图3:用户确认隔离响应安全,然后释放到LLM应用
此外,当用户通过CLI应用审查更新的服务器配置时,他们可以让LLM护栏权衡服务器配置的安全性。截至本文撰写时,mcp-context-protector附带了对LlamaFirewall的支持。开发人员可以通过实现自己的GuardrailProvider子类来集成其他护栏框架。
清理ANSI控制序列
正如我们最近关于MCP的一篇文章所讨论的,ANSI控制字符可用于隐藏提示注入攻击,并以其他方式混淆在终端中显示的恶意输出。Claude Code和其他基于shell的LLM应用的用户可以打开mcp-context-protector的ANSI控制字符清理功能。此功能不是剥离ANSI控制序列,而是将转义字符(十六进制值为1b的字节)替换为ASCII字符串ESC。这样,输出 rendered无害,但可见。
当用户通过CLI应用审查服务器配置时,此功能自动打开:
图4:服务器配置审查期间ANSI控制字符 rendered可见
思维链审计的限制
使用MCP本身将mcp-context-protector插入LLM应用和MCP服务器之间有一个明显的缺点:mcp-context-protector无法完全访问对话历史,因此无法使用该数据来决定工具调用是否安全或符合用户的意图。一个执行 exactly那种类型分析的AI护栏例子是AlignmentCheck,它集成到LlamaFirewall中。AlignmentCheck使用微调模型来评估代理工作流的整个消息历史,以寻找代理偏离用户陈述目标的迹象。如果检测到错位,工作流可以被中止。
由于mcp-context-protector本身是一个MCP服务器,设计上,它缺乏全面评估整个思维链所需的信息,并且无法利用AlignmentCheck。诚然,我们在本系列的第二篇文章中证明了恶意MCP服务器可以窃取用户的对话历史。但原则上,构建 intentionally违反其他安全控制的安全控制是一个坏主意。我们不建议编写依赖LLM披露用户对话历史的MCP工具,尽管协议有告诫。
因此,如果您的用例需要完整的思维链审计,您需要将其更深入地集成到您的应用中,而不是mcp-context-protector可能的方式。
手动配置审查和警报疲劳
这种方法的第二个限制在于手动审查过程本身及其可能给人工干预带来的负担。在某些环境中,MCP服务器可能频繁更改其配置。例如,发布提供访问大型复杂API的MCP服务器的供应商可能会在其API每次更改时更新其MCP服务器。随着时间的推移,警报疲劳将产生影响,用户可能会错过恶意行为的迹象(或者更糟,完全停止使用MCP安全控制)。因此,如果MCP服务器频繁更新,组织应考虑由安全工程师进行集中审查,而不是依赖 individual用户使用像mcp-context-protector这样的工具保护自己的部署。
在您的组织中采用mcp-context-protector
由于mcp-context-protector本身是一个符合标准的MCP服务器,它可以与任何主机应用和任何下游服务器一起使用。理想情况下,它应该用于安装在任何类型应用中的每个MCP服务器,包括通用聊天机器人、AI辅助代码编辑器和其他代理。
目前mcp-context-protector中实现的安全控制只是开始;开发人员可以添加任何适合其组织用例的控制类型。例子可能包括数据丢失预防检查或对从网络检索的数据的额外护栏。
如果您开始使用mcp-context-protector并有任何反馈,或者您想贡献新功能或错误修复,请访问GitHub上的存储库并提交问题或拉取请求。