从 Web 应用中提取数据库访问控制策略(OSDI 2026)
原题:Extracting Database Access-Control Policies From Web Applications
一句话总结:Ote 假设 Rails 应用中真正决定 SQL 查询的代码核心主要由简单条件和数据流组成,用带界的 concolic execution 记录查询及其路径条件,再用 SQL 视图合并、化简和裁剪生成可审计策略;在 diaspora、Autolab 和 Odin 上最多约 5 小时完成提取,并发现手写策略中的过宽、过窄授权以及一个被外部库配置静默禁用的访问检查。
问题与动机
Web 应用通常没有一份独立的数据库访问策略。授权逻辑分散在控制器、模型、模板和多个查询过滤条件中。缺少检查或过滤条件写错,可能直接暴露敏感数据;即使没有漏洞,维护者也很难从不断演化的代码中恢复“应用实际上能读什么”。
已有显式策略框架要求应用重写为特定编程模型,难以覆盖遗留 Rails 应用。Ote 选择反向提取:先观察应用在不同数据库状态、会话参数和请求参数下发出的查询,再把“查询在什么条件下被发出”整理成 SQL view-based policy。人需要审阅这个策略,决定它是否符合隐私要求;确认后还可以交给 Blockaid 一类执行器,约束后续代码变更。
论文的目标不是给出完整性和紧致性的形式保证。作者把输出定义为三个理想目标:允许应用可能发出的全部查询、尽量少暴露信息、并保持 SQL 表示可读。Ote 的实际结果依赖输入空间边界、支持的 SQL 子集、人工提供的数据库约束,以及 LLM relevance judge 的判断。
关键观察 / 隐含假设
- 观察 1:查询发出核心通常比完整 Web 应用简单。 作者对三个应用的分析认为,影响查询发出的代码主要是查询结果是否为空、基本值比较、遍历查询结果以及把前一个查询的值传给后一个查询;模板渲染、日志和 HTML 格式化通常不在这个核心中(§4.1)。
- 依赖假设:查询使用参数化 SQL,且查询相关表达式主要由 Ote 已插桩的简单操作构成。
- 可能失效场景:正则校验、字符串拼接、复杂数值运算或外部库逻辑决定查询时,符号值可能被具体化,导致遗漏查询或生成过宽、过窄的策略。
- 观察 2:不相关分支造成的路径爆炸是实际瓶颈。 五个 handler 在不剪枝时超过 10 小时仍未完成,论文估计可能需要数天;很多分支只影响页面展示,不影响数据访问(§4.6、§7.4)。
- 依赖假设:LLM coding agent 能根据条件位置和源代码判断某分支是否影响查询或状态。
- 可能失效场景:动态 Rails 元编程、外部库副作用或缺少上下文会使 judge 把相关分支判为无关。Ote 将 unsure 和格式错误按 relevant 处理,并要求人工复核。
- 假设 1:可以用有限数据库模型代表足够多的应用状态。 原型默认每张表最多 2 行、每个查询最多返回 1 行,并由用户提供唯一性和包含关系等约束(§4.4)。
- 证据强度:中。三个应用上输出有用,但该边界无法保证覆盖真实多行循环、排序和数据规模相关行为。
- 假设 2:PSJ view 足以表达目标应用的访问策略。 Ote 的策略语言支持 project-select-join 查询,复杂 SQL 只能近似处理;否定条件、一般聚合和部分 outer join 尚未完整支持(§3.2、§7.3)。
- 证据强度:中。评测中的应用能被处理,但论文明确报告了需要重写或丢弃部分语义的查询。
核心方法
Ote 的输入是 Rails handler、应用数据库约束和 Docker 化应用。驱动器用带界的 concolic execution 运行 handler:输入同时有具体值和符号表达式,分支条件被记录,SMT solver 通过否定已走过的条件生成新输入。执行器在修改过的 JRuby 和 Rails 数据层上运行,每次执行输出查询记录、分支记录以及可回溯的 stack trace(§§4.3–4.5)。
Ote 只在可能属于查询发出核心的操作上维护符号状态。记录 QUERY 时保存 SQL、参数和结果是否为空;记录 BRANCH 时保存条件及实际走过的方向。通过把前序查询结果表示为符号行,后续查询可以引用例如 r1.course_id 这样的数据流。数据库约束同时用于限制有效状态和简化路径条件。
为缓解路径爆炸,Ote 异步调用基于 Codex CLI 的 relevance judge。judge 查看分支和对应 stack trace,回答 relevant、irrelevant 或 unsure。驱动器跳过不相关分支的否定,不再探索已覆盖的相关条件序列;judge 的结果和解释保留下来供审计。人工可以用 RELEVANCE-HINT 注释纠正 Rails 或外部库语义。
每条查询轨迹先被转换为 conditioned query:一个 SQL 查询及其发出所需的前序查询、分支条件。Ote 删除必然成立或未被后续使用的条件,传播等式,合并只在单个分支方向上不同的记录,并移除被更宽条件 subsume 的记录(§5.2)。随后,它把条件逐项 conjoin 到关系代数表达式中,生成 SQL view;请求参数不能出现在最终策略中,因此会依据列约束消除这类参数(§5.3)。
最后,Ote 使用扩展后的 Blockaid 检查一个 view 是否已被其余 view 包含,分别做 handler 内和跨 handler 的裁剪。用户也可以先添加更宽但不涉及隐私的 view,再让裁剪器删除冗余的窄 view。这个步骤把“哪些条件只是业务逻辑、哪些条件是隐私边界”的判断留给人,同时避免手工推导 view subsumption。
设计取舍
- 带界的 concolic execution 对动态语言更实用,但牺牲覆盖保证。 修改 JRuby 可透明追踪 Rails 执行,代价是只支持 Rails 和有限的符号操作;输入行数、返回行数和数据库约束决定了探索边界。
- LLM judge 换取可扩展剪枝,但引入新的审计面。 不相关分支的静态识别在 Ruby/Rails 中很难,LLM 能处理动态代码上下文;但其 verdict 没有形式保证,而且每次调用可能耗时数分钟。论文人工检查了所有 irrelevant verdict,并将 unsure 视为 relevant。
- PSJ view 提高可读性和裁剪效率,但会损失复杂 SQL 语义。 LEFT JOIN、COUNT、时间戳比较等在评测中被重写、拆分或近似。输出策略因此可能比真实行为更宽或更窄,必须由熟悉 SQL 和应用的人员复核。
- 策略默认偏紧,减少漏授权风险,但增加审阅负担。 Ote 保留业务条件,生成的 view 通常多于手写策略。对于 profile 这类本来应公开的数据,用户需要显式添加更宽 view 才能压缩结果。
实验与结果
- 在 diaspora(超过 850k 用户、50 张表)、Autolab(26 张表)和 Odin(17 张表)三个真实 Rails 应用上评测;实验使用 Google Compute Engine c3-standard-176、48 个并行 executor、Z3 4.11.2 和修改后的 JRuby(§§7.1–7.2)。
- 端到端提取最多约 5 小时;启用 relevance-based pruning 后,原本超过 10 小时未完成的 handler 得以完成(§7.4)。
- 最终策略规模被压到每个应用约 24–144 个 SQL views,达到可供人工审阅的数量级(§7.3)。具体 view 数量随 handler 和裁剪阶段变化,表 2 给出了完整矩阵。
- relevance judge 产生了 600 多个 irrelevant verdict;论文逐一人工复核,且这些 verdict 集中在有限的代码位置。Odin 分支较少,没有启用该优化(§7.5)。
- 与既有手写策略比较时,Ote 找到 Autolab 中把 disabled course 的五类记录错误开放给 course assistant 的过宽授权,也找到手写策略遗漏的 diaspora remote person、通知数据以及 Autolab 课程附件等过窄授权(§7.6)。
- 审阅 Autolab 输出时,作者发现所有 submission view 都没有检查
assessments.exam。追踪后确认lazy_column被错误配置为exam?而非列名exam,使检查方法总是返回 falsy,静默禁用了访问检查(§7.6)。 - 在 diaspora 中加入 4 个更宽的 profile views 后,裁剪器删除了 39 个 profile-related views 中的 36 个,说明人工负责隐私语义、工具负责包含关系化简的分工有效(§7.7)。
论断—证据表
| 论断 | 证据 | 评测边界 | 置信度 |
|---|---|---|---|
| Ote 能在真实 Rails 应用上提取可审阅的策略 | 三个应用的抽取结果和最终 view 数量(§§7.1、7.3,表 2) | Rails;每表至多 2 个符号行;每查询至多 1 行;PSJ 近似 | 强 |
| relevance judge 对可扩展性很重要 | 启用剪枝后最多约 5 小时完成;禁用时部分 handler 超过 10 小时(§7.4) | 仅对长路径 handler 启用;gpt-5/Codex CLI;人工复核 verdict | 强 |
| 提取策略能暴露手写策略和代码中的授权错误 | Autolab、diaspora 的过宽/过窄策略差异及 exam? 配置 bug(§7.6) | 两个应用有既有手写策略;结果依赖人工审阅 | 强 |
| 输出策略可以被进一步压缩而保留相同信息 | profile 场景加入 4 个宽 view 后删除 36/39 个相关 view(§7.7) | 依赖用户理解“哪些业务条件不是隐私条件” | 中 |
| Ote 不保证完整和紧致 | 有界路径探索、未插桩操作、LLM 判断错误和 PSJ 近似(§3.2、§4.7) | 论文给出设计级限制,未提供形式覆盖率 | 强 |
批判性分析
论证链条
论文的主链条基本闭合:作者先测量查询相关代码的结构和路径爆炸,再用选择性符号追踪减少实现范围,用 relevance judge 缩小路径空间,最后把轨迹转换成可审计的 view。三个应用中的策略差异确实能定位手写策略和应用代码错误。
但“提取的策略比手写策略更准确”不能理解为无条件结论。Ote 的输出是应用在有限模型和有限路径上的观察结果。复杂条件可能被漏掉,SQL 近似可能改变信息含义,judge 也可能漏判。论文展示了实用价值,没有证明输出覆盖全部可发出的查询。
假设压力测试
最脆弱的假设是简单查询发出核心。Rails 应用若在查询参数、URL 校验、权限判断或模型回调中使用未插桩字符串和算术操作,Ote 可能看不到真实依赖。论文通过把 URL 固定为合法值、改写非参数化查询来绕开部分问题,但这些改动也说明工具需要应用专家配合。
“每个查询至多返回一行”适合许多 lookup,但会压低对列表页、批量关系和循环查询的覆盖。论文的 view 生成算法可以表达前序查询结果的组合,但实验输入边界仍限制了它看到的组合数量。生产数据库中多行结果、排序稳定性和数据规模触发的分支需要单独测量。
LLM judge 的错误不会只影响性能:若相关分支被判为 irrelevant,最终策略可能丢失访问条件。作者通过人工复核和保守的 unsure 规则降低风险,但没有报告独立审阅者之间的一致性、误判率或 judge 版本变化下的稳定性。
实验可信度
应用选择覆盖社交网络、课程平台和教学社区,且包含此前已有手写策略的对照,适合验证“能否帮助审计”。性能实验也明确报告了并行度、solver、LLM 模型和执行时间。缺口在于样本仍只有三个 Rails 应用,且应用被做过兼容性修改;论文没有在更多框架、复杂 SQL 或真实生产 trace 上验证泛化性。
策略正确性主要靠作者人工检查和与手写策略比较。手写策略本身并非金标准,作者发现的差异需要结合应用意图判断。论文没有给出完整的独立 ground truth、系统化漏查询率或对所有生成 view 的形式等价验证。因此,结果充分支持“辅助审计有用”,不足以支持“策略自动正确”。
系统性缺陷
- 人工成本仍然存在:用户要提供数据库约束、写 relevance hints、判断 SQL 近似是否安全、审阅策略并决定是否 broadening。论文明确说这些步骤需要 Rails、SQL 和应用领域知识(§7.8)。
- 部署耦合较强:当前实现绑定修改过的 JRuby、Rails 和 MySQL;缓存被关闭,查询在 tmpfs 上运行。论文未评估这些设置对真实延迟、缓存相关访问路径和运维成本的影响。
- 安全风险可能转移到审阅流程:策略看起来合理可能造成 automation bias。论文在 §9 提出这个风险,但没有实验验证审阅者是否会过度信任输出。
- 策略可读性是瓶颈:几十到上百个 view 仍可能难以由人理解,尤其当条件来自业务逻辑而非隐私边界。SQL DSL 和策略可视化是合理的后续方向,但当前系统没有提供。
- LLM 依赖的可复现性有限:judge 使用 Codex CLI、gpt-5 和超时重试。论文记录了 verdict,但没有把 judge 替换成确定性分析器,也没有评估模型更新对路径集合的影响。
局限与后续工作
- 局限 1:策略语言和查询支持不完整。 PSJ 无法自然表达否定条件,复杂 join、aggregation、ordering 和字符串操作需要近似或暂不支持。后续应在带完整 SQL 语义的基准上测量近似导致的过宽/过窄比例。
- 局限 2:输入空间边界限制覆盖。 每表 2 行和每查询 1 行便于终止,但不适合系统性验证多行循环。可以构造逐步增加行数的实验,观察新增路径和 view 是否收敛。
- 局限 3:相关性判断依赖 LLM。 应比较 LLM judge、静态切片和人工标注在误判率、成本、总提取时间上的差异,并对模型升级做回归测试。
- 局限 4:跨框架泛化尚未验证。 论文认为方法可推广到其他语言,但当前实现只支持 Rails。下一步应在至少一种 Python 或 JavaScript ORM 上复现“查询发出核心”假设。
- 局限 5:人机审阅界面不足。 需要把 view、生成它的 transcript、输入、源码 stack trace 和相关 judge verdict 联动展示,并测量审阅者找 bug 的时间和误报率。