写作
一条提示词加Claude Fable 5:我如何修复了API的五个安全漏洞
VLOP透明度仪表盘的背后运行着一个小型FastAPI服务——一个仿照TikTok Research API设计的结构化查询API,提供聚合后的欧盟DSA透明度数据。它的若干端点是有意公开的:交互式查询构建器、自然语言"提问"框、概览数据流。业余规模服务上的公开端点,正是安全债务悄然积累的地方,因为没有任何东西强迫你去检查。
于是我让Claude Code去检查——它搭载的是Fable 5,Anthropic新一代Claude 5系列的首个模型。提示词只有一行:"对API做一次安全检查,修复发现的所有漏洞。"返回的是一个包含五项独立修复的拉取请求,每项都带回归测试,外加它对自己diff的自审。
它发现了什么
Webhook回调中的SSRF缺口。该API允许查询携带一个callback_url,任务完成时会向其发送POST——这是典型的服务器端请求伪造(SSRF)攻击面。原有的防护拦截了私有、回环、链路本地和云元数据地址段,但黑名单方式与这个问题的形状不匹配:它漏掉了那些既非私有也非公网的地址段,比如运营商级NAT(100.64.0.0/10)。修复将检查反转——回调目标现在必须可全球路由,否则一律拒绝。
CSV公式注入。查询结果可导出为CSV,而数据集包含来自第三方透明度报告的自由文本字段。以=、+、-或@开头的单元格在Excel或Sheets中打开时会被当作公式执行——也就是说,别人发布的报告里的一个值,可能在研究人员的机器上运行代码。带这些前缀的文本单元格现在会被中和处理,服务器端和仪表盘的客户端导出都做了。
不设上限的请求体与查询复杂度。公开查询端点无需认证即可接受完整的结构化查询模型。请求体能有多大、一个查询能堆叠多少条件,原本都没有限制。现在超限的请求体在进入任何解析工作之前就会被以413拒绝,查询模型本身也限定了每个条件的取值数量、每个子句的条件数量和每个请求的字段数量。
API密钥校验中的时序侧信道。密钥原本用字典查找校验,遇到第一个不同字符就会提前终止比较——原则上,响应时间会泄露密钥前缀。现在改为对所有已配置密钥做常量时间比较。
外加若干零散加固——分页参数的边界之类,属于按清单逐项扫描能发现、而忙碌的维护者会漏掉的小项。
让我意外的部分
这个拉取请求触发了另一个AI——Gemini Code Assist——的自动审查,留下两条建议。Fable 5在行动前把两条建议都对照实际源码做了核实,并在其中一条上发现机器人的论证不完整。Gemini指出,把攻击者可任意指定长度的Content-Length头解析成整数可能消耗CPU。没错,但是小事。更尖锐的问题——Fable 5在回复中指出并解释了——是Python 3.11+拒绝解析超过约4,300位的整数并直接抛出异常,所以一个病态的请求头本会产生500错误,而不是预期的413。它还把Gemini硬编码的修复方案泛化为跟随配置上限取值,并补充了一个发送5,000位数字请求头的回归测试。一个AI审查另一个AI对第一个AI代码的审查、并且在分歧中站在正确一边——这不在我2026年的预测清单上。
我的收获
这与我之前写的合规工作中的LLM应用遥相呼应:胜算在于产出可验证的结构化任务。对一个小代码库做安全扫查正是如此——把一份有限的清单(注入面、SSRF、侧信道、资源耗尽)穷尽式地过一遍,每个发现都能通过读代码确认,每个修复都能用测试钉死。"穷尽而枯燥",正是如今模型稳定胜过疲惫人类的地方。
判断仍然留在我这里。指标端点是否可以保持免认证、演示密钥在非生产环境是否可接受、内存任务存储对演示服务是否够用——这些是关于该服务为何而存在的威胁模型判断,模型也没有假装替我做这些决定。包含测试的完整diff见这个拉取请求;测试套件共122项,全部通过。