
Simon Willison 和 Alex Garcia 刚刚发布了 Datasette 的两个安全版本(1.0a39 和 0.65.4),整个过程是一次彻底的 AI 辅助安全审计。事情起源于 Sevban Dönmez 报告的几个问题,后来演变成持续一周的协作——用 Claude Fable 5.1、GPT-5.6 和 GPT-6 Astra 来排查那些混合了公开表和私有表访问模式的授权 Bug。Willison 明确表示,以后所有开发工作都会加入前沿模型的安全审计流程。这算是 AI 代理安全研究正式进入生产工作流的真实案例了。
有意思的地方不在于 LLM(大语言模型)能发现 Bug,而在于整个工作流:人机怎么分工、怎么确保每个问题都有两个独立审查者、以及怎么设计提示词来挖掘那些细微的授权逻辑错误。
Willison 和 Garcia 在一个私有的共享仓库里协作。大多数问题的处理流程是这样的:
这种模式保证了测试编写和修复实现是独立的。如果同一个人既写测试又写修复,可能会把自己的思维模型同时编码进两个产物里。分开来做,就能得到对安全需求的两种独立理解。
模型负责跑初轮审计。人类负责验证、写测试、实现修复。模型不直接写生产代码,它们负责识别攻击面和潜在漏洞。
他们用三个不同的前沿模型跑了同样的审计:
每个模型的训练数据、推理模式、盲区都不一样。用多个模型跑同一套审计能提高覆盖率。如果三个模型都标记了同一个问题,那大概率是真的。如果只有一个模型标记,就需要人工仔细审查,判断是假阳性还是其他模型漏掉的细微 Bug。
这不是集成投票,而是把模型多样性当作纵深防御。每个模型都是独立的审查者,用自己的视角来看代码库。
这些 Bug 被描述为"非常细微",涉及公开表和私有表的混合场景。Datasette 允许把某些表配置为公开,另一些配置为私有。当查询涉及两种类型的表时,授权逻辑需要正确执行访问控制。
这类授权 Bug 可能包括:
模型可能是通过分析公开表和私有表逻辑交叉的代码路径来发现这些问题的。前沿模型擅长追踪复杂条件语句中的数据流,也能发现授权检查缺失或顺序错误的场景。
Willison 没有公布具体的提示词,但从结果可以推断出结构。有效的授权 Bug 安全审计提示词需要:
完整的代码库上下文:模型需要看到整个授权层,而不是孤立的函数。这意味着要么用大上下文窗口,要么对代码库进行智能分块。
明确的威胁模型:提示词要明确说明你要防御什么。对 Datasette 来说,就是防止未认证用户或低权限用户访问私有表数据。
示例攻击模式:提供常见授权 Bug 的例子(IDOR、权限提升、信息泄露),让模型知道要找什么。
聚焦边界条件:让模型专门检查公开和私有数据交互的代码路径、权限变更的地方、用户输入影响授权决策的地方。
一个合理的提示词结构大概是这样的:
You are auditing a Python web application for authorization vulnerabilities. **Threat model**: An unauthenticated user should not be able to access data from tables marked as private. A low-privilege user should not be able to escalate their permissions. **Focus areas**:
- Code paths where public and private tables are queried together
- Permission checks in API endpoints
- Error messages that might leak information about private tables
- Query construction logic that uses user input **Common patterns to look for**:
- Missing authorization checks before database queries
- Authorization checks that happen after data is fetched
- Logic errors in permission inheritance or delegation
- Information disclosure through error messages, timing, or metadata Review the following code and identify potential authorization vulnerabilities.
For each issue, explain the attack scenario and the affected code path. [Insert codebase or relevant modules here] 审计工作流是这样的:
┌─────────────────┐
│ Security Issue │
│ Reported │
└────────┬────────┘ │ ▼
┌─────────────────┐
│ Run AI Audit │
│ (3 models) │
└────────┬────────┘ │ ▼
┌─────────────────┐
│ Human Review │
│ of Findings │
└────────┬────────┘ │ ▼
┌─────────────────┐
│ Split Work: │
│ Person A writes │
│ test, Person B │
│ implements fix │
└────────┬────────┘ │ ▼
┌─────────────────┐
│ Both Humans │
│ Review Fix │
└────────┬────────┘ │ ▼
┌─────────────────┐
│ Ship Security │
│ Release │
└─────────────────┘ 关键决策点:
| 方面 | 收益 | 风险 |
|---|---|---|
| 多模型 | 覆盖率提高,视角多样化 | 成本更高,需要排查更多假阳性 |
| 测试/修复分工 | 独立验证,发现实现错误 | 比一个人同时做更慢,需要协调 |
| AI 生成的结果 | 发现人类遗漏的细微 Bug,可扩展到大代码库 | 假阳性,可能遗漏依赖上下文的漏洞 |
| 私有仓库 | 在修复前保持发现保密 | 需要纪律约束避免在公开提交中泄露细节 |
| 需要人工审查 | 验证可利用性,确定修复优先级 | 如果假阳性太多,人会成为瓶颈 |
最大的风险是对模型输出的过度依赖。模型擅长模式匹配,但不擅长理解业务逻辑和真实世界的可利用性。一个被标记的问题可能在技术上是正确的,但由于其他缓解措施(限速、网络隔离、输入验证)实际上不可利用。
需要追踪:
失败模式:
这可能是一个 Datasette 测试套件中用于混合公开/私有表授权 Bug 的测试:
import pytest
from datasette.app import Datasette @pytest.mark.asyncio
async def test_private_table_not_leaked_via_join(): """ Ensure that joining a public table with a private table does not leak private table data to unauthenticated users. """ ds = Datasette( memory=True, metadata={ "databases": { "test": { "tables": { "public_table": {"allow": True}, "private_table": {"allow": {"id": "admin"}}, } } } }, ) # Populate tables
db = ds.add_memory_database("test") await db.execute_write("CREATE TABLE public_table (id INTEGER, name TEXT)") await db.execute_write("CREATE TABLE private_table (id INTEGER, secret TEXT)") await db.execute_write("INSERT INTO public_table VALUES (1, 'Alice')") await db.execute_write("INSERT INTO private_table VALUES (1, 'classified')") # Attempt to join as unauthenticated user
response = await ds.client.get( "/test.json?sql=SELECT public_table.name, private_table.secret " "FROM public_table JOIN private_table ON public_table.id = private_table.id" ) # Should return 403 Forbidden, not the joined data
assert response.status_code == 403 assert "private_table" not in response.text 这个测试重现了攻击场景:一个未认证用户试图通过与公开表联表来访问私有表数据。如果查询成功或者响应泄露了私有表信息,测试就会失败。
适合使用这种工作流的场景:
不适合使用这种工作流的场景:
核心洞察是:模型擅长发现潜在问题,但验证可利用性和实现修复必须靠人。分工模式确保了独立审查,同时不会让总工作量翻倍。如果你已经在做人工安全审计,加入 AI 辅助审计能以合理成本提高覆盖率。如果你根本没有在做安全审计,先从人工审查开始,建立对威胁模型的直觉,等理解了业务逻辑再加入 AI 辅助。