审计Ask Astro LLM问答应用 - Trail of Bits博客
今天,我们发布第二个开源AI安全审计项目:分析一个开源检索增强生成(RAG)应用中的安全问题,这些问题可能导致聊天机器人输出投毒、文档摄取不准确和潜在拒绝服务。此次审计延续了我们之前在流行计算机视觉框架YOLOv7中发现11个安全漏洞的工作。
具体来说,我们在Ask Astro中发现了四个问题。Ask Astro是一个基于风险投资公司A16Z的RAG应用参考架构构建的开源聊天机器人应用。RAG是通过上下文知识库增强大型语言模型(LLM)训练数据集中未包含信息的最有效技术之一。
在这篇博客中,我们回顾了Ask Astro中部署的RAG架构,然后深入探讨我们的技术发现,这些发现可分为两个高级类别:
架构问题:缺乏手动审核或文档删除功能,使攻击者能够用有害信息毒化聊天机器人的输出,这与最近的学术文献(特别是Carlini等人,2023年)相呼应。
实现缺陷:多个实现错误可能危及文档摄取的准确性(通过GitHub问题的分割视图投毒、Weaviate客户端中的GraphQL注入)或威胁财务拒绝服务(问题扩展提示中的提示注入)。
最后,我们提供了几个最佳实践,帮助RAG部署避免类似问题。如果您的项目需要类似检查,请联系我们。
关于Ask Astro
Ask Astro是一个开源聊天机器人,为Astronomer(Apache Airflow工作流的编排工具)提供技术支持。它是完全自动化的,部署后无需管理。
Ask Astro是此类审计的良好候选者有两个主要原因。首先,该项目积极维护,具有高质量的代码库和复杂的设计,展示了开发者使用现代ML开发栈可以实现的目标。还付出了大量努力创建清晰的文档和编写自动化测试。
其次,该项目的主要目的是作为社区教育工具。它作为RAG参考实现进行结构和文档化,并宣传其遵循A16Z的RAG应用参考架构。此外,其实现使用了构建RAG应用的流行工具代表样本:
- Weaviate,存储文档嵌入的向量数据库;
- Langchain,基于Python的LLM编程框架;
- Apache Airflow,在Ask Astro中用于管理文档检索和处理的工作流编排系统。
Ask Astro可能成为许多新RAG开发者的起点。因此,许多其他RAG应用可能遵循类似设计并遇到与Ask Astro相同的挑战。
该应用具有相对较窄的攻击面。它包括图1中图示的两个主要工作流:文档摄取和生成用户问题响应。
图1:Ask Astro数据流图
文档摄取
Ask Astro使用一系列通过Astronomer触发的Apache Airflow工作流从以下来源摄取文档:
- Apache Airflow、Astronomer CLI、Astronomer Cosmos和Astronomer SDK的官方文档
- 官方Astronomer博客
- 对Astronomer Registry贡献的Python源代码,其中包含用户提交的Astronomer和Airflow工作流组件
- OpenLineage项目中两个GitHub仓库的文档
- Apache Airflow仓库的GitHub问题
- 带有airflow标签的StackOverflow线程
通过HTTPS下载源材料后,Ask Astro将其推送到Weaviate(一个开源向量数据库)。在此步骤中,Weaviate向OpenAI发出API调用,将文档文本转换为嵌入,Weaviate在本地保存。
答案生成
当用户通过API提交问题时,Ask Astro执行多步骤过程检索相关文档并生成答案。此过程首先要求LLM生成原始问题的两个重新表述版本,以帮助从向量数据库检索相关文档。这些问题被转发到Weaviate,后者使用余弦相似性搜索检索最相关的文档。然后Ask Astro调用Cohere Reranker API(一个知名的LLM提供商)根据这些文档与用户原始问题的相关性重新排序。然后LLM过滤器移除模型评估为与用户问题无关的文档。最后,LLM生成面向用户的答案,最终文档列表打包到问题的上下文窗口中。
对抗环境中RAG的局限性
RAG是使LLM更知识渊博、更响应业务及其客户需求的强大方式。RAG系统也遭受与LLM相同的众所周知缺陷,如提示注入和幻觉。此外,RAG系统依赖于放入向量数据库的输入的可靠性。在大多数非平凡应用(如Ask Astro)中,用于增强LLM知识库的文档包括不受信任的文档。包含不受信任文档的能力不是异常,而是期望的功能:人们希望对网站、评论和用户提供的文档进行RAG。
由于基本不可判定性结果,自动算法无法完美确定论坛帖子或GitHub评论是否包含误导信息或其他恶意内容。任何足够有用的RAG系统都将不可避免地索引误导性或恶意内容。
对数亿图像-文本对的投毒攻击的学术研究表明此问题很重要。许多RAG应用使用远较小的数据集作为向量数据库的输入,使得对向量数据库的投毒攻击在经济上可行。
我们对Ask Astro的审计说明了这些风险如何在实践中显现。我们展示攻击者可以操纵应用的知识库,方式与Carlini等人的《毒化Web规模训练数据集是实用的》中描述的两种投毒攻击类型平行,即前置运行和分割视图投毒:
- 分割视图投毒攻击通过改变Web上托管数据的可变性,在策展人或系统设计者选择将其引入系统知识库后原地更改资源。
- 相比之下,前置运行投毒发生在攻击者了解数据摄取计划时,在摄取运行前发布恶意内容,仅在摄取完成后立即删除。
发现
[TOB-ASTRO-0001] 通过源材料删除的数据投毒
严重性:高
影响:向量数据库投毒导致不准确或恶意答案,难以检测,缺乏手动数据库审查
场景:攻击者使用一组傀儡账户在系统开始摄取运行前在社区论坛上发布完整讨论线程。摄取运行完成后,攻击者删除线程,对论坛版主隐藏。没有任何一致的过程将源材料删除传播到向量数据库,了解新文档摄取间隔的攻击者可以轻松将任意文本注入知识库。
讨论:缺乏任何资源删除检查为前置运行创造了现成机会。如实现,Ask Astro没有解决摄取资源中不准确信息的保障措施,缺乏删除不准确或敏感文档的设施。唯一例外是跳过分数为零或更低的Stack Overflow答案。社区讨论、GitHub问题评论和Astronomer Registry中的源代码被视为真相来源,与官方文档一样权威。
此发现主要归因于Ask Astro作为参考实现的性质。可以理解,此类项目不会实现大多数组织在生产环境中需要的数据审核过程。
[TOB-ASTRO-0002] 通过GitHub问题的分割视图投毒
严重性:低
影响:通过公开可见源材料的向量数据库投毒导致不准确或恶意答案
场景:攻击者在文档摄取前在AskAstro仓库中创建新GitHub问题。当呈现为Markdown时,这些问题形成具有权威作者身份的伪造问题线程。攻击者然后可以将不准确或恶意知识插入向量数据库,并使其看起来源自官方来源。
讨论:文档摄取例程在处理GitHub问题时有两个错误。这些错误启用两种方法对向量数据库进行分割视图投毒攻击。当GitHub问题摄取例程运行时,问题及其评论通过GitHub API下载并使用基本Markdown模板连接:
|
|
图2:通过Markdown模板连接问题
然后使用一系列正则表达式从结果文档中去除样板文本。其中几个正则表达式包含与re.DOTALL标志使用的贪婪.*序列,这使得点字符类匹配换行符:
|
|
图3:贪婪正则表达式匹配超出预期
问题评论的后处理创建第二个注入漏洞,让攻击者伪造整个问题线程。使用Markdown模板呈现后,每个问题线程作为单个字符串保存在向量数据库中。相关文档通过LangChain“stuff”链在问题回答期间传递到LLM的上下文中,该链连接相关文档。由于上下文由非结构化文本组成,没有稳健的方法分离文档。因此,攻击者可以通过发布模仿Ask Astro问题Markdown模板的问题评论来模拟新问题线程。
注意此技术绕过开发者可能用于区分可信数据与不可信数据的一些缓解措施的力量。当文档数据库包括不同用户之间的对话时,识别最权威语句的简单启发式方法是查找与销售软件(在Ask Astro情况下为Astronomer)的供应商关联的电子邮件地址或用户名。面对此评论伪造向量,此方法失效。如果攻击者可以伪造整个评论线程,他们也可以伪造每个评论的作者信息,击败经常推荐的缓解措施。
此问题已通过PR #325到ask-astro仓库修复。
[TOB-ASTRO-0003] Weaviate客户端中的GraphQL注入
严重性:中
影响:检索非公共文档,但仅当Ask Astro向量数据库与非公共数据库共享基础设施时
场景:Weaviate的GraphQL模式允许攻击者在一个查询中从两个集合检索文档。考虑一个组织托管一个公共聊天机器人,该机器人利用公共文档(如API参考材料)和一个使用敏感私有信息的内部聊天机器人。攻击者知道这一点,并针对面向公共的聊天机器人构建特制查询以泄漏仅内部可用的敏感文档。
讨论:Ask Astro API服务器使用Weaviate Python客户端库版本3。weaviate-client的所有v3版本在用于转义GraphQL查询参数的_sanitize_str函数中有一个错误。未转义的引号前加反斜杠,而似乎已转义的引号保持不变。以下正则表达式实现此功能:
|
|
正则表达式将任何 preceded by a backslash 的引号视为充分转义。此逻辑错误处理多个连续反斜杠在引号前的情况。包含子串\“的输入不被转换,因为look-behind断言失败。实际上,子串\“不是转义引号,而是转义反斜杠后跟未转义引号。将此值直接插入GraphQL查询中的引用字符串将终止字符串,导致服务器将后续内容解释为查询语法,而不是字符串文字的一部分。
由于许多应用(包括Ask Astro)将不受信任的用户输入传递到Weaviate过滤器中,此错误创建可行的注入攻击,尽管效用有限。Weaviate的GraphQL模式未定义任何突变——即客户端只能读取数据,不能写入数据——因此利用无法更改向量数据库。GraphQL允许客户端通过连接多个操作在一个请求中组合它们,很像堆叠SQL查询,但此技术不可用于对抗Weaviate客户端。客户端生成的第一个GraphQL操作是匿名的,意味着它不指定查询名称。GraphQL服务器无法将匿名操作与其他操作组合,并将拒绝包含匿名查询和任何第二个操作的任何GraphQL请求。然而,Weaviate的GraphQL模式允许攻击者在一个查询中从两个集合检索文档,创建潜在数据泄漏漏洞。
此发现已报告为weaviate-python-client仓库中的问题#954,并通过PR #1134修复。
[TOB-ASTRO-0004] 问题扩展提示中的提示注入
严重性:低
影响:过度资源消耗或财务拒绝服务
场景:回答问题的第一步是GPT-3.5 Turbo提供同一问题的两个替代表述。使用提示注入技术,攻击者可以提交导致模型生成超过两个问题甚至用任意字符串回复的问题。攻击者影响的查询可能导致模型在重新表述步骤中产生过大量输出,导致拒绝服务。
讨论:最后,我们到达提示注入,最常讨论的LLM错误类别。阻止不良类别的LLM输出是不可判定的,因此在一般情况下无法解决(Glukhov等人,2023年)。因此,针对提示注入的防御根本上不完美,提示注入必然发生。
在这种情况下影响最小,因为产生的重新表述问题有助于从向量数据库检索文档,而不是在回答用户问题的最终请求中。与之前的错误不同,此攻击不能用于从聊天机器人征求错误答案。Ask Astro使用较便宜的GPT-3.5 Turbo进行问题重新表述,减少了此问题的财务影响。然而,如果单个OpenAI API密钥授予两个模型的权限,该密钥仍可能触发全局资源限制,从而关闭整个账户。此外,Astronomer.io告知我们在生产中使用各种速率限制和反DDoS措施;我们建议生产部署采取类似措施。
从RAG到财富
任何成功RAG部署的核心挑战是确保引入向量数据库的信息的完整性。Ask Astro从多个来源摄取数据,攻击者可能用错误信息毒化这些来源。缺乏持续完整性验证过程使得毒化数据可能保留在数据库中,即使原始论坛帖子或GitHub问题被删除。
为解决此挑战,我们推荐以下最佳实践:
- 任何RAG应用都需要工具和过程来审计和维护向量数据库。适当的审计和审核工具将有助于减轻数据投毒风险并帮助调试和评估。每当内容审核者删除不受信任的Web源时,自动化过程应 promptly 从数据库中删除它。对内容源的所有更新,无论可信与否,也应传播到向量数据库。
- 仅同步向量数据库与底层实时Web资源不足。开发者不应将向量数据库准确性的责任卸载给论坛版主和其他第三方,因为这些参与者可能没有与RAG开发者相同的目标和动机。因此,人类必须对向量数据库进行持续审查,查找不准确或不相关的内容。数据审查系统应跟踪人类审核者在数据集来源和谱系记录中采取的行动。
- Ask Astro的GitHub问题处理错误表明RAG系统的数据摄取过程是另一个可能影响系统输出质量的错误来源。每个文本解析或数据处理步骤应仔细测试,输入包括真实世界数据、边缘案例和模拟攻击负载的混合。
- 最后,Weaviate库中的GraphQL注入错误说明了应用安全中的一个基本原则:两个系统组件之间的每个接口都带有一组必须理解和减轻的潜在攻击向量。此外,这些攻击向量的分析必须是特定于上下文的。例如,回想GraphQL注入错误的影响取决于与Ask Astro向量数据库同一Weaviate部署中存储的数据。因此,彻底威胁建模是对于具有像RAG聊天机器人一样多移动部件的机器学习应用不可或缺的步骤。
获取帮助
如果您的组织正在设计或构建使用RAG或任何其他专业方法的机器学习系统,我们的安全工程师可以帮助进行威胁建模、设计和基础设施审查、代码审查、模糊测试等。我们专注于应用安全和机器学习的独特交叉点,为您的应用提供整体安全评估。联系我们,看看我们是否适合您。
如果您喜欢这篇文章,请分享: Twitter LinkedIn GitHub Mastodon Hacker News
页面内容 关于Ask Astro 对抗环境中RAG的局限性 发现 从RAG到财富 获取帮助 最近帖子 Trail of Bits的Buttercup在AIxCC挑战赛中获得第二名 Buttercup现已开源! AIxCC决赛:记录表 攻击者的提示注入工程:利用GitHub Copilot 在新员工期间发现NVIDIA Triton中的内存损坏 © 2025 Trail of Bits。 使用Hugo和Mainroad主题生成。