CodeQL 2.27.3 已自动部署:升级前必查 5 个风险

2026 年 11 月 3 日,GitHub 发布 CodeQL 2.27.3 更新:加入 Python 3.15 语法、JSON 数据扩展和可选的 AI 威胁模型,同时调整了多项查询。官方 CodeQL 文档却把该版本日期记为 2026 年 10 月 20 日——现在值得看,是因为它已经开始自动部署到 GitHub 代码扫描,GHES 用户则要等到 3.24 版本。

下文凡标注“推导”的,均为我根据官方信息作出的判断,不是官方结论;其余功能信息均来自官方页面或官方变更日志。

两个发布日期背后:升级已经发生

GitHub 的公告日期是 2026 年 11 月 3 日,CodeQL CLI 官方变更日志则将 2.27.3 标为 2026 年 10 月 20 日。第三方报道也记录了这两个时间点,并将其解释为“版本先发布、公告稍后发布”。这不一定是文档错误,因为 CodeQL CLI、GitHub Changelog 和 GitHub Action 打包并不是同一份发布记录,但它提醒用户:看到公告日期,不等于工具当天才进入流水线。

更重要的是部署方式。GitHub 官方说明,每个新版 CodeQL 都会自动部署给 github.com 上的代码扫描用户;2.27.3 的功能也会进入 GHES 3.24。使用更老 GHES 的团队可以手动升级 CodeQL。

因此,真正需要检查的不是“要不要点击升级”,而是以下五项:

  1. 仓库是否已经切换到新版 CodeQL;
  2. 自定义查询是否依赖旧版控制流图结构;
  3. 数据扩展是否使用 YAML,以及能否迁到 JSON;
  4. Python 查询是否接入了团队自己的威胁模型;
  5. 升级后是否出现结果数量或告警位置变化。

四个变化,不只是“多认一种语言”

变化 官方新增能力 对普通用户意味着什么 升级时应检查
Python 3.15 支持一元加号匹配模式、Unicode 17 标识符、frozendict 与 sentinel 新代码不再因语法不认识而漏掉数据流 用 3.15 语法文件跑一次查询
数据扩展 .json 文件可按 JSON 解析,其他文件仍按 YAML 解析,并支持 Java 风格注释 配置可沿用 YAML 的结构,迁移时不必重写组织方式 确认扩展文件名与测试文件对应
AI 威胁模型 可选择启用 LLM 生成数据模型,但默认不内置来源 团队可以自行定义什么算不可信输入 不要误以为启用后自动覆盖所有 AI 数据
查询与运行库调整 多个查询减少误报或接入威胁模型 告警数量可能变化,部分旧结果会消失 对比升级前后的查询输出

其中,Python 部分不只是“解析器接受新语法”。官方还加入了 frozendict 构造的数据流建模,以及 unicodedata.iter_graphemes、threading.serialize_iterator 和 threading.concurrent_tee 的数据流建模。通俗地说,CodeQL 现在更可能沿着这些 Python 3.15 API 判断数据如何流动。

但“支持新语法”仍不等于“所有 Python 3.15 项目都已获得完整覆盖”。这是边界推导:官方列出了若干已支持项,没有声称覆盖全部新特性。因此,团队不应把升级当作 Python 3.15 安全性的终点,而应拿真实业务中的新语法和标准库调用验证。

JSON 数据扩展:省掉 YAML 改造吗

此次更新允许数据扩展使用 JSON。官方文档写得很具体:文件扩展名为 .json 时按 JSON 解析,其他扩展名仍按 YAML 解析;JSON 文件还允许 // 和 /* ... */ 形式的 Java 风格注释。

JSON 与现有 YAML 数据扩展采用相同结构,因此迁移的核心不是重新设计模型,而是确认序列化工具能否保留字段层级、列表顺序和特殊字符。官方还更新了 codeql test run 的加载规则:运行 <test>.ql 或 <test>.qlref 时,除了原有的 <test>.ext.yml,现在也会自动加载 <test>.ext.json。

可以先做一次文件级检查:

# 查看本机 CodeQL 版本
codeql version

# 找出仓库中的数据扩展文件
find . -type f ( -name '*.ext.yml' -o -name '*.ext.json' )

# 查找可能依赖旧控制流图接口的自定义查询
rg -n 'Completion|DirectSuccessor|BooleanSuccessor|ReturnSuccessor' .

这里的重点不是立刻批量改名,而是确认测试目录中的命名规则。若测试名是 login.ql,对应扩展使用 login.ext.json 即可进入自动加载路径;若仍保留 .yml,CodeQL 也不会因此失效。

需要注意,JSON 允许注释是 CodeQL 数据扩展解析器的能力,不代表所有 JSON 工具都接受注释。若扩展文件还要进入其他配置校验流程,直接用通用 JSON 校验器检查时,注释可能引发报错。稳妥做法是让 JSON 保持标准兼容,把说明移到相邻文档;若必须使用注释,则先确认整条工具链都能解析。

AI 威胁模型:启用后并不会自动懂 AI

这是最容易被宣传语带偏的一项。官方明确写道:CodeQL 新增了一个可选择的 AI 威胁模型,用于处理 LLM 生成数据,但它不包含任何内置来源模型,团队需要通过数据扩展自行定义来源。

换句话说,启用选项只是打开规则入口,不会自动识别“模型输出”“提示词内容”或“工具返回值”。如果不定义来源,相关 Python 查询仍可能把 AI 数据视为可信输入。这是根据官方描述作出的边界推导。

官方同时说明,py/xxe、py/xml-bomb 和 py/nosql-injection 查询现在会尊重配置的威胁模型。默认行为不变,仍使用远程流作为不可信来源;自定义数据扩展中的来源现在也能被这些查询纳入。

对于正在开发 AI 应用的团队,可以按下面的顺序检查:

  • 列出模型输出进入代码或工具调用的位置;
  • 将这些位置定义为数据扩展中的来源;
  • 确认相关 Python 查询已启用对应威胁模型;
  • 用测试查询验证来源是否能沿数据流到达危险操作;
  • 对比升级前后的告警,区分新增真实风险与模型边界变化。

如果只是开启选项而不建立来源,不能据此宣称“AI 生成数据已经纳入扫描”。真正产生价值的是“来源定义、查询启用、路径验证”三者同时完成。

自定义查询才是升级前的高风险区

本次最明确的破坏性变化发生在 GitHub Actions。官方说明,Actions 的控制流图开始使用共享 CFG 库;如果自定义查询依赖特定节点、边或基本块边界,可能需要调整。旧的 Completion 类已被移除,应改用 DirectSuccessor、BooleanSuccessor 和 ReturnSuccessor 等 CFG 边标签。

这意味着,风险不只在“能否编译”,还在“能否继续准确判断路径”。普通用户可能看不到底层结构变化,却会发现某些告警消失或路径改变。其原因是旧查询依赖的控制流节点和边表示发生变化,并不代表对应安全问题自动消失。

升级前可先搜索高风险调用:

rg -n 
  'Completion.|DirectSuccessor|BooleanSuccessor|ReturnSuccessor|.getNext|basic block|BasicBlock' 
  --glob '*.ql' --glob '*.qll' .

随后分别运行旧版与 2.27.3 查询,对同一提交保存结果。比较重点不只是告警总数,而是:原路径是否仍被识别、关键节点是否仍可达、同一风险是否换了位置或拆成多条告警。这是我的复算建议,而非官方提供的迁移脚本。

其他兼容性变化相对局部:C/C++ 的资源未释放查询会识别通过局部别名释放资源的情况;C# 可简化布尔表达式查询在类型信息不完整时减少误报;Java/Kotlin 的 SSRF 与未校验重定向查询能识别大小写不敏感的固定允许列表比较;Ruby 则把更多 Grape::API 请求访问器视为远程流来源。它们都可能改变告警数量,不应把“告警变少”直接解释为“风险下降”。

参考来源

评论区

0 条评论

登录后可评论。

我家大橘 52 阅读