AI 代理文件上传需要明确的硬边界
AI 代理文件上传需要严格检查大小、类型和目标,防止日志、导出文件和客户文件到达错误的接收方。

上传端点就是一个出站数据通道,即使工程师把它称为附件功能。一旦 AI 代理可以附加日志、导出文件、屏幕截图或客户文件,一句含糊的指令,例如「把这个发给支持团队」,就可能变成无法挽回的数据泄露。
AI 代理文件上传需要对字节、内容和接收方设置明确的硬边界。应把这些边界放进执行上传的操作中,而不是写在代理提示词里,也不要依赖审查人员在忙碌一天结束时发现一个不良文件名。
上传操作必须声明哪些内容可以离开系统
安全的上传流程要先把每个文件视为一个用途明确的对象。用途决定最大大小、允许格式、允许的接收方、保留要求,以及发送前是否必须由人审批。如果 API 接受任意 multipart 请求体和调用方提供的 URL,你就创建了一条通用的数据外泄通道,只是开发者接口做得很友好。
人们常混淆两件事:从不可信客户端接收文件,以及代表代理发送文件。传统的上传指南重点是保护服务器不受恶意文件攻击。代理上传同样需要这些保护,但更直接的风险是防止数据被过度发送。某个 PDF 可能非常适合解析,却完全不适合交给工单系统。
不要定义通用的 upload_file 操作,而应定义有名称的上传用途。例如,diagnostic_bundle 可以允许将压缩的支持包发送给一个支持系统接收方。invoice_export 可以允许将 CSV 发送给财务接收方。这两种用途都不应在同一个请求中同时接受路径、接收方 URL 和任意文件。
一个小型契约就能让边界清晰可见:
{
"purpose": "diagnostic_bundle",
"file_path": "/private/tmp/app-diagnostics-2025-03-08.zip",
"destination_id": "support-case",
"case_reference": "CASE-1842"
}
调用方选择已批准的用途,并提供业务操作所需的元数据。上传服务将 support-case 映射到自己管理的接收方,不允许调用方用问题评论、文档或工具响应中嵌入的 URL 替换接收方。
文件路径也要受到控制。代理只能从指定的暂存目录中选择文件,或者由服务根据已知输入自行生成附件。允许代理指定任意可读路径,就等于允许它读取配置文件、SSH 材料、浏览器数据或其他用户的导出文件。
大小限制需要测量两个维度
文件限制应在服务存储、扫描或转发之前拒绝过大的请求体。在 HTTP 边缘层,如果存在 Content-Length,先用它执行限制,然后在读取过程中继续统计字节数,因为客户端可能省略或伪造这个标头。
限制必须符合用途。客户 CSV 的 25 MB 限制,与压缩诊断包的 25 MB 限制,并不是同一个决定。解析器读取 CSV 时,文件可能扩展为更大的内存分配。压缩包解压后也可能比传输大小大很多倍。因此应同时设置传输大小限制和处理后大小限制。
不要让代理把被拒绝的文件拆成许多合法请求,除非接收方明确支持分块上传,并且你的服务会跟踪总大小。否则,10 MB 规则会变成 100 个分片的传输,原本以为拥有的保护全部失效。
尽早拒绝,并返回能让代理安全恢复的响应:
{
"error": "attachment_too_large",
"purpose": "diagnostic_bundle",
"observed_bytes": 12582911,
"max_bytes": 8388608,
"safe_alternatives": [
"create_redacted_diagnostic_bundle",
"attach_selected_log_window"
]
}
这个响应很重要。如果只返回「上传失败」,代理可能会尝试另一个目标、压缩文件,或持续重试。应告诉它下一步允许执行什么操作,同时不要通过调试消息泄露被拒绝的文件。
缓冲也是一个容易被忽略的失败点。许多框架会在应用代码看到大小之前,先把 multipart 请求解析到内存或临时目录中。应让 Web 服务器、框架解析器、反向代理和应用读取器使用一致的限制。最小限制最终会生效,但某个意外更大的层仍可能在较小的层拒绝请求前消耗磁盘空间。
还要测量文本标准化、图像转换、文档提取和压缩包解包后的大小。只限制原始附件,并不能控制后续生成材料的资源占用或泄露风险。
文件名和 MIME 标头几乎不能证明什么
文件类型检查需要独立证据,因为文件扩展名和 Content-Type 标头都来自发送方。代理可能并无恶意,只是转发了误导性的标签。支持工具也可能把每个附件都标为 application/octet-stream。无论哪种情况,接收方都应根据字节内容和允许的结构作出判断。
OWASP 的 File Upload Cheat Sheet 建议使用扩展名允许列表,不信任 Content-Type 标头,由服务器生成文件名,并将上传内容存放在 Web 根目录之外。这些建议依然有效,但代理工作流还需要增加一条规则:在服务联系远程接收方之前,先根据已命名的用途验证文件类型。有效的 PDF 并不自动适用于所有上传用途。
可以使用多种检查,分别回答不同问题:
- 扩展名告诉你发送方声称文件是什么。
- 签名字节告诉你内容开头是否符合声称的格式。
- 有边界的解析器告诉你这些字节是否足够符合格式,可以安全处理。
- 内容检查告诉你文件是否包含该用途禁止的材料。
对于 CSV 导出,可以只允许 .csv 和 UTF-8 文本,解析有限的样本,并拒绝嵌入的二进制数据或异常宽的行。对于 PDF,应验证 %PDF- 签名,应用大小限制;如果必须检查页面,就使用有时间和内存限制的解析器。对于图像,应在处理前解码尺寸。文件大小适中的图像,解码后仍可能分配过多内存。
避免笼统接受「压缩包」类型。ZIP、TAR 和 GZIP 各不相同,也都有自己的检查工作。如果业务流程不需要压缩包,就拒绝它。因为用户偶尔会需要某种格式而接受它,正是通用附件端点出现的原因。
在服务端重命名已接受的文件。清理原始文件名后,可以把它作为显示元数据保留,但不要未经转义就将它用作文件系统路径、对象存储键或 Content-Disposition 值。文件名可能包含控制字符、具有欺骗性的 Unicode、路径分隔符,以及会改变下游日志的字符串。
目标检查必须经得住重定向
接收方允许列表必须准确标识可以接收文件的地点。允许 https://example.com 还不够,因为 HTTP 客户端可能跟随重定向到另一台主机、解析到内部地址,或接受不同的端口。
将目标保存为服务器端记录,固定协议、主机、端口、路径前缀、凭据身份和允许的用途。操作只接收 destination_id,绝不接收自由填写的端点。如果接收方要求在路径中加入案件 ID,应根据受约束的标识符构建路径,而不是从代理那里接收完整 URL。
每次发送时,HTTP 客户端都应执行以下检查:
- 除非有记录在案的内部例外,否则必须使用 HTTPS。
- 建立连接前,将请求的主机和端口与目标记录进行匹配。
- 默认禁用重定向。如果接收方确实需要重定向,则在发送下一个字节前,按照同一条目标记录验证每个重定向目标。
- 拒绝 IP 字面量、回环地址、链路本地地址和私有地址范围,除非该目标明确对应受控的内部服务。
- 固定允许的路径前缀和 HTTP 方法,不要允许访问整个主机。
第四点通常被称为 SSRF 防护,确实如此。它还可以防止代理跟随任务描述中的 URL,造成意外泄露。能够访问内部网络的上传客户端,绝不能把任务文本当作联系某个地址的授权依据。
不要转发原始授权上下文。用于向案件管理 API 发送请求的凭据只能属于该接收方和该操作。会复制任意代理标头的文件上传网关,会更容易受到标头注入,也会让代理能够间接选择凭据。
记录重定向后的最终 URL,但要从运行日志中删去查询参数值。查询字符串经常包含签名上传令牌。记录目标很有用,但把可直接使用的授权令牌写入日志是不负责任的。
日志需要一条有意设计的导出路径
日志是团队最容易低估的附件类别。它们可能包含请求标头、客户标识符、SQL 片段、堆栈跟踪、内部主机名,有时还包括完整的请求或响应正文。日志位于开发者目录中,并不意味着可以安全地通过电子邮件发送或上传。
不要靠一条「删除机密」的指令解决问题。代理可能漏掉某些格式,过度遮盖内容,或把可疑字符串判断为无害上下文。应创建诊断包生成器,读取已知文件,应用确定性的过滤器,并在暂存目录中生成新的工件。
实用的过滤策略可以删除完整字段,而不是试图找出所有可能的机密模式。默认删除 Authorization、Cookie、Set-Cookie、API 密钥字段、会话标识符和请求正文。当需要关联记录时,用稳定的本地令牌替换客户标识符。将时间范围限制在事故窗口内,不要发送数周的历史记录。
例如,与原始 HTTP 跟踪相比,下面这种诊断记录更安全:
{
"time": "2025-03-08T14:22:11Z",
"request_id": "local-7f3c",
"method": "POST",
"route": "/v1/reports",
"status": 502,
"upstream": "reporting-service",
"authorization": "[removed]",
"body": "[omitted]"
}
包生成器应生成清单,列出文件名、字节数、哈希值和已应用的过滤器。这样审查人员无需打开每个附件,也能检查具体内容。接收方也能据此识别被截断或遭修改的上传内容。
数据库导出需要更严格的规则。不能因为工单写着「发送一个样本」,就让代理附加生产环境导出文件。应生成仅包含架构的工件、只查询获准列的专用查询结果,或生成合成复现数据。如果事故确实需要真实客户记录,应将其作为独立操作,明确目标、范围,并要求人工审批。
屏幕截图也应同样谨慎。它们可能包含客户账户、消息、浏览器标签页、通知和本地路径。与其把一个宽泛的截图目录交给代理,不如通过受控工具裁剪截图,或生成范围明确的截图。
压缩包和办公文档隐藏的不止一个文件
压缩包会在一个上传文件中创建第二组文件。发送前应检查成员列表,并限制成员数量、压缩字节数、解压字节数、路径深度和嵌套层级。拒绝使用绝对路径、.. 路径遍历、重复名称或符号链接的条目。
一个磁盘上只有 2 MB 的 ZIP 文件,解压后可能膨胀到耗尽工作进程或接收方资源的大小。这通常被称为解压炸弹,但问题并不只来自恶意输入。构建系统可能意外生成巨大的压缩包,代理也可能附加第一个看起来像导出文件的内容。
办公文档同样需要谨慎处理。现代文档格式通常包含 ZIP 容器、嵌入媒体、元数据、评论、修订记录和外部关系。文档页面看起来已经删减内容,但其内部包仍可能保留旧文本或作者信息。如果工作流只需要渲染后的内容,应根据获准数据生成新的 PDF,而不是转发可编辑的原始文档。
不要在请求路径中递归「清理」任意文档。解析和重写复杂格式本身就有安全性和可靠性成本。对于范围明确的工作流,应只接受范围明确的生成工件。对于例外文档,应将其交给人工审查流程,由人检查实际文件和目标。
操作契约应让不安全的请求无法执行
面向代理的工具应暴露与你的控制措施相匹配的选项,而不是一个原始 HTTP 请求构造器。如果工具提供 url、headers、file_path 和 method,策略就已经失去了大部分约束。
应使用这样的请求模式:不可信字段描述意图,可信记录提供权限。下面的例子把接收方、凭据和允许的文件类别都置于代理控制之外:
{
"action": "send_attachment",
"purpose": "customer_export",
"destination_id": "finance-import",
"artifact_id": "exp_8c4e1a",
"note": "March reconciliation correction"
}
服务将 artifact_id 解析为由自己创建,或通过独立接收流程接受的暂存对象。服务自行计算摘要并检测类型,将 destination_id 解析为固定的接收方记录,并在发送时加入接收方凭据。代理永远看不到该凭据,也不能在审批后替换另一个接收方。
预检结果应暴露足够的信息,让人能够作出知情决定:
{
"decision": "approval_required",
"artifact": {
"name": "reconciliation-2025-03.csv",
"bytes": 482913,
"detected_type": "text/csv",
"sha256": "a4d1...c09e"
},
"destination": {
"label": "Finance import",
"host": "imports.example.internal",
"path": "/v2/reconciliation"
},
"reason": "customer_export requires approval"
}
不要只给审查人员显示文件名和批准按钮。应显示测得的大小、检测到的类型、目标主机、目标标签和用途。如果文件敏感,应在审批界面显示抽样分类结果或清单,而不是完整文件内容。
让工件 ID 短期有效且只对应一个用途。暂存的诊断包不应在支持案件关闭后,仍能作为通用上传对象重复使用。创建工件时就将它绑定到用途和接收方,并在较短的操作窗口后使其失效。
重试需要幂等性。网络故障很常见,代理也会频繁重试。应在操作层生成幂等令牌,将它绑定到工件摘要和目标,并且只为同一次预期发送重复使用。带着更改后的路径或摘要重试时,不得继承之前的授权。
人工审批只有在标记真实边界时才有用
审批不能替代验证。人无法仅从一个弹窗中可靠识别 ZIP 炸弹、伪装文件或重定向缺陷。审批适合处理策略无法自动决定的事项:这份特定的客户导出文件是否应因这起事故发送给这个接收方。
对于高敏感度发送、新接收方、生产环境导出文件和范围较大的诊断工件,应逐次调用审批。如果工件范围小且用途已获批准,同时目标和内容都受到约束,就可以让常规工件自动发送。让人审批每一份测试报告,只会让他们产生疲劳并习惯于不看内容就点击通过。
审批记录应绑定工件摘要、声明的用途和目标记录。任意一项发生变化,都应废弃审批。仅凭文件名不够,因为两个文件可能同名,但字节内容不同。
Sallyport 可以让代理无法接触 HTTP 上传所用的凭据,其逐密钥审批选项适合每次都需要人工决定的发送。但这并不能免除应用层工件契约的必要性,因为网关无法推断某个客户 CSV 是否应该进入支持工单。
保留两种审计视图:一种记录哪个代理运行实例获得了执行权限,另一种记录每次传输尝试及其结果。审计记录应包含摘要、实际字节数、类型判定、用途、接收方记录、决定、响应状态和时间。如果要保留机密和完整文件内容,应将其存放在其他位置,甚至可以完全不保留。
在代理发现拒绝路径之前测试它们
只在正常路径上成功的策略还没有完成。建立一个能记录实际收到的完整请求的隔离接收方,然后使用能触发每条边界的测试样本。
先向测试接收方发送一个普通上传请求:
curl -i -X POST https://receiver.test/attachments \\
-H 'Authorization: Bearer test-token' \\
-F 'file=@fixtures/diagnostic.zip;type=application/zip' \\
-F 'case_reference=CASE-1842'
成功测试应确认方法、最终主机、路径、摘要和大小。真正有价值的是证明接收方什么都没有收到的测试。应断言超限请求体会在转发前被拒绝,伪造的 text/plain 标头无法让二进制内容通过,未列入允许列表的目标不会收到连接。
测试样本应包含以下情况:
- 扩展名有效,但签名字节不匹配。
- 压缩包解压后的大小超过限制。
- 允许的主机将请求重定向到不允许的主机。
- 包含授权标头和客户电子邮件地址的日志样本。
- 使用相同幂等令牌重试,但文件字节内容不同。
测试期间要检查服务器日志。你需要确认两件事:传输没有发生,而且自己的日志没有保留被拒绝的正文、Bearer 令牌或签名 URL。团队经常修复了网络路径,却把同样的敏感材料留在异常跟踪中。
要通过生产代理使用的同一个代理工具接口运行测试。如果面向内部的安全 HTTP 客户端允许代理包装器选择原始 URL,或绕过工件暂存路径,它就帮不上忙。
让安全路径比原始路径更容易使用
当获准路径缓慢、含义不清,或无法处理日常支持工作时,团队就会绕过上传控制。应构建一小组人们真正需要的工件:脱敏诊断包、范围狭窄的导出文件、生成的报告,以及边界明确的事故截图。让代理可以按名称轻松请求每一种工件。
不要把通用原始上传器加入代理工具列表。如果工程师遇到特殊情况需要它,应要求通过交互式运维路径操作,由工程师在完整上下文中选择文件和接收方。因为这种操作无法可靠地自动分类,这种不便是合理的。
成功发送和被拒绝的发送都应认真审查。大量超大诊断包意味着诊断工件设计有问题。反复尝试将日志发送到新主机,可能说明目标列表确实需要经过论证后扩展,也可能说明代理提示词正在试图绕过控制。只有把用途、文件判定和接收方决定放在一起记录,才能看出两者的区别。
我会先做一个简单的改动:从代理上传操作中移除自由填写的 URL 和任意文件路径。操作只接受暂存工件、命名用途和目标 ID 后,大小限制和内容检查才有可靠的位置发挥作用。
常见问题
文件大小限制足以保证 AI 代理上传安全吗?
不能。大小限制只能限制错误传输的数据量。你还需要对文件进行分类,在可行时检查实际内容,并将接收方限制为有明确理由接收这类数据的目标。
如何让 AI 代理上传文件,同时不持有 API 凭据?
应把代理上传视为带凭据的出站数据通道。代理只负责请求上传操作,独立的网关则在发送前检查文件、目标、范围和是否需要审批。
可以信任 multipart 上传中的 MIME 类型吗?
不要信任它。MIME 类型和文件扩展名都来自客户端,可能被伪造。应根据允许列表检查扩展名,检查文件签名,并在接受前使用有资源限制的解析器解析格式。
AI 代理上传应允许多大的附件?
应按照最小的合法工件来设置限制,而不是为未来可能出现的工件预留空间。如果导出文件和日志的合理大小不同,就为它们设置不同的路径,并在完整缓存请求体前拒绝超限文件。
文件上传的目标允许列表应包含哪些内容?
目标允许列表不能只有主机名。应固定协议、主机、路径前缀、端口、身份验证凭据、重定向行为,以及每个目标可以接收的文件类别。发生重定向后,还要解析并再次检查最终目标。
让 AI 代理上传应用日志安全吗?
通常不安全。完整日志经常包含授权标头、会话材料、电子邮件地址、内部 URL 和客户请求内容。应创建专用的诊断包,在上传前删除或遮盖这些字段。
如何在上传流程中安全地允许 ZIP 文件?
转发前先检查压缩包。限制压缩大小、解压大小、条目数量、嵌套深度和文件路径,然后对每个解压出的成员执行常规类型检查。看似无害的压缩包可能隐藏巨大的或不允许的内容。
什么时候应要求人工审批代理上传?
当操作越过敏感性边界时应要求审批,例如发送客户数据、生产环境导出文件,或将文件发送给新接收方。让人审批每个无害的构建工件会造成疲劳,也会让人养成不看内容就批准的习惯。
如何测试 AI 代理文件上传策略?
使用能记录方法、标头、请求体大小、校验和及重定向处理的隔离测试接收方。然后测试超大文件、伪造的内容类型、解压后超限的压缩包、禁止的主机,以及被拒绝后的重试。
代理文件上传的审计日志应记录什么?
良好的审计记录应包含发起请求的代理进程或会话、文件摘要和实际大小、检测到的类型、选定的目标、授权决定、时间戳、请求结果和任何重定向。除非有独立且合理的保留方案,否则不要把文件正文存进审计记录。