GitHub 在 2026 年 9 月 9 日发布 CodeQL 2.27.0。这个版本最值得开发者关注的变化有三项:CodeQL CLI 和 bundle 开始原生支持 Linux ARM64,Rust 增加 rust/command-line-injection 安全查询,Code Scanning Default Setup 可以使用组织的私有注册表配置获取自定义查询和查询包。
它们分别解决了扫描基础设施、Rust 应用安全和企业内部规则分发的问题。对使用 ARM64 自托管 Runner、维护 Rust 服务,或把 CodeQL 接入私有依赖体系的团队来说,这次升级不只是查询数量增加,还会改变扫描环境和权限配置的边界。
先看 2.27.0 带来了什么
CodeQL 2.27.0 的 Default suite 现在包含 498 个安全查询,覆盖 170 个 CWE;Extended suite 另外启用 131 个查询,覆盖 32 个 CWE。本次版本新增了 1 个安全查询,核心变化可以归纳为:
| 变化 | 对工程的直接影响 |
|---|---|
| Linux ARM64 成为一等平台 | ARM64 自托管 Runner 可以直接运行 CodeQL CLI 和 bundle |
| 新增 Rust 命令行注入查询 | 扫描不受控命令行参数进入进程执行路径的风险 |
| 私有注册表配置接入 Default Setup | 组织可以从私有 Git 源或 Docker Registry 获取自定义查询和查询包 |
| CodeQL CLI 更倾向平台专用包 | 安装脚本需要从通用压缩包切换到平台包 |
| GitHub Actions 查询和多语言模型更新 | 可能出现新的告警,也可能减少旧的误报 |
因此,升级后的第一步不应该是直接把告警数量和上一个版本比较。要先确认 Runner 架构、查询包来源、组织权限和自定义模型是否都在新版本的支持范围内。
Linux ARM64 支持,解决的是扫描基础设施问题
CodeQL 2.27.0 把 linux-arm64 作为一等平台,提供平台专用的 CLI 和 bundle 下载包。过去使用 ARM64 机器做安全扫描时,团队往往需要额外准备 x86 构建节点、模拟层,或者自行维护一套能运行的工具链。现在可以让扫描任务直接运行在 Linux ARM64 主机上。
这对自托管 Runner 尤其有用。很多低功耗服务器、云端 ARM 实例和内部构建集群已经是 ARM64 架构,但编译、测试和安全扫描经常因为工具链不齐而被迫回到 x86。CodeQL 本身能够在 ARM64 上运行后,团队可以把代码构建和数据库提取放在同一类机器上,少处理一层架构差异。
不过,官方也明确说明 ARM64 二进制只通过平台专用下载包提供,不包含在组合版 codeql.zip、codeql-bundle.tar.gz 或 codeql-bundle.tar.zst 中。安装脚本如果仍然无条件下载通用包,就会出现“版本已经支持 ARM64,但 Runner 仍然找不到可执行文件”的问题。
一个更稳妥的下载逻辑是先识别运行环境,再选择对应资产:
1 | 系统:Linux |
不要只看操作系统名称。linux-amd64 和 linux-arm64 在 GitHub Actions 的 Runner 标签、容器基础镜像和缓存目录上都可能有不同约定。安装后应该显式运行 codeql version,再执行一次最小数据库创建任务,确认 CLI、查询包和语言提取器都能正常工作。
Rust 命令行注入查询为什么重要
Rust 的内存安全特性不能自动阻止命令注入。只要应用把外部输入拼进 shell 命令,攻击者仍然可能改变命令的含义。一个简化的风险示意是:
1 | use std::process::Command; |
真正的问题不在 Command 这个类型本身,而在于不可信输入是否进入了可解释的命令行。修复通常需要避免调用 shell、把程序名和参数分开传递,并对业务允许的参数做白名单约束。仅仅把字符串中的几个特殊字符替换掉,往往难以覆盖不同 shell 和不同调用链上的语义差异。
CodeQL 2.27.0 新增的 rust/command-line-injection 查询,目标就是发现这类不受控制的命令行。它把一个过去需要安全工程师手工检查的数据流问题,加入了 Rust 默认安全检查的范围。团队需要注意两件事:第一,新增查询会带来新的告警,告警不等于已经确认存在可利用漏洞;第二,查询无法替代代码审查,业务边界、输入来源和部署环境仍然需要人工判断。
升级后如何处理 Rust 告警
可以按下面的顺序处理:
- 先确认输入来源。HTTP 参数、消息队列内容、配置文件和用户上传数据都可能是外部输入,但信任边界取决于实际部署方式。
- 再确认执行方式。直接调用固定二进制并把参数作为独立参数传递,与
sh -c、cmd /C或其他 shell 解释器的风险不同。 - 最后判断业务约束。即使输入不是公网可控,也要检查是否能被低权限用户、租户或被入侵的上游服务影响。
如果团队有自定义 Rust 数据扩展模型,还要留意 2.27.0 的兼容性变化。官方变更日志提到,Rust trait item 的规范路径改为 <crate::Trait>::item。引用旧路径的自定义模型需要同步更新,否则扫描结果可能缺少预期的数据流关系。
私有查询包开始进入 Default Setup
很多组织的安全规则不会全部放在公开查询包中。团队可能有内部框架、私有依赖或专门针对业务协议的查询,这些内容通常存放在私有 Git 仓库或私有 Docker Registry。CodeQL 2.27.0 允许 Code Scanning Default Setup 使用组织级私有注册表配置,在获取自定义 queries 或 packs 时完成认证。
这个变化让 Default Setup 更适合企业内部规则分发,但也引入了清晰的权限边界。组织需要配置合适的 Git Source 或 Docker Registry 私有注册表,并确认扫描任务只获得读取查询包所需的权限。不要为了让扫描通过,把一个可以写入源码仓库或发布包的凭据直接交给所有 Runner。
可以把权限拆成三层:
1 | 代码仓库:扫描任务读取待分析代码 |
三者不应该共享同一个高权限 token。尤其是自托管 Runner,扫描过程会接触源代码、依赖和分析结果,Runner 被其他任务复用时,还要检查工作目录清理、凭据注入和网络出口策略。
其他变化也可能改变告警基线
2.27.0 并不只针对 ARM64 和 Rust。升级时还应注意这些变化:
- C/C++ 查询把 PostgreSQL
libpq的PQexec、PQexecParams、PQprepare、PQsendQuery、PQsendQueryParams和PQsendPrepare纳入 SQL 注入 sink。使用这些接口的项目可能出现此前没有的告警。 - Java/Kotlin 增加了 Micronaut 的建模,覆盖 HTTP 控制器、WebSocket、配置注入、数据访问和安全注解等场景。
- GitHub Actions 查询修正了
author_association在事件 payload 不包含对应字段时的判断。某些原来被错误认为具有保护作用的条件,升级后可能触发新的告警。 - Java 9 和 Java 10 的语言支持已经标记为弃用,官方计划在 2027 年 1 月移除;Java 7 和 Java 8 仍会继续支持。
- 通用多平台
codeql.zip已被弃用,未来应改用codeql-PLATFORM.zip这样的平台专用包。当前版本还会发出提醒,可以用CODEQL_ALLOW_ALL_PLATFORMS_DIST=true暂时压制提示,但这不是长期迁移方案。
这些改动说明安全扫描结果不是一个永远不变的数字。查询、框架模型、事件语义和提取器都会更新,团队需要把升级后的告警重新分级,而不是简单地把新增告警全部标成误报。
给安全和平台团队的升级清单
1. 先做架构和安装包矩阵
把 Runner 的系统、架构、容器镜像和 CodeQL 下载资产列成矩阵。至少覆盖 Linux AMD64、Linux ARM64 和本地开发机使用的架构,避免 CI 能跑但本地无法复现,或者 ARM64 Runner 被错误安装了组合包。
2. 用基线区分新发现和真实回归
在升级前保存一次扫描结果,升级后分别统计新告警、关闭告警和位置变化。对 Rust 命令行注入、C/C++ PostgreSQL sink 和 GitHub Actions author association 变化,单独建立复核清单,不要直接用总数判断版本好坏。
3. 给私有查询包配置最小读取权限
查询包的读取凭据只应该能够访问必要的 Git 源或 Registry。扫描任务失败时,先检查注册表配置、Runner 网络和查询包版本,再考虑扩大权限。权限扩大应有期限和审计记录。
4. 检查自定义模型的升级兼容性
Rust trait path、Ruby 控制流图以及部分语言框架模型都有变化。自定义 query、model pack 和扩展库应该放在一个最小测试仓库中,升级 CodeQL 后先验证查询是否还能得到预期路径,再推广到所有项目。
结语
CodeQL 2.27.0 的意义在于,安全扫描开始更贴近实际工程的两端:一端是 ARM64 自托管基础设施,另一端是 Rust、私有框架和内部查询规则这些具体的开发场景。Linux ARM64 支持可以减少架构迁移成本,Rust 命令行注入查询补上了一个重要的安全检查面,私有注册表配置则让组织规则更容易进入默认扫描流程。
升级时最重要的动作不是立刻追求更少的告警,而是让告警变化可解释。先固定运行环境,再保存版本基线,最后复核新增查询和权限边界,团队才知道这次升级到底发现了什么,也知道哪些问题值得进入修复计划。