CodeQL 2.27.0:Linux ARM64 原生运行与 Rust 命令行注入检测值得升级吗

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.zipcodeql-bundle.tar.gzcodeql-bundle.tar.zst 中。安装脚本如果仍然无条件下载通用包,就会出现“版本已经支持 ARM64,但 Runner 仍然找不到可执行文件”的问题。

一个更稳妥的下载逻辑是先识别运行环境,再选择对应资产:

1
2
3
4
系统:Linux
架构:aarch64 / arm64
资产:codeql-linux-arm64.zip
或 codeql-bundle-linux-arm64.tar.gz

不要只看操作系统名称。linux-amd64linux-arm64 在 GitHub Actions 的 Runner 标签、容器基础镜像和缓存目录上都可能有不同约定。安装后应该显式运行 codeql version,再执行一次最小数据库创建任务,确认 CLI、查询包和语言提取器都能正常工作。

Rust 命令行注入查询为什么重要

Rust 的内存安全特性不能自动阻止命令注入。只要应用把外部输入拼进 shell 命令,攻击者仍然可能改变命令的含义。一个简化的风险示意是:

1
2
3
4
5
6
7
8
9
use std::process::Command;

fn run_tool(user_argument: String) {
// 仅作风险示意:不要把未验证输入交给 shell 解释器。
let _ = Command::new("sh")
.arg("-c")
.arg(format!("tool {}", user_argument))
.status();
}

真正的问题不在 Command 这个类型本身,而在于不可信输入是否进入了可解释的命令行。修复通常需要避免调用 shell、把程序名和参数分开传递,并对业务允许的参数做白名单约束。仅仅把字符串中的几个特殊字符替换掉,往往难以覆盖不同 shell 和不同调用链上的语义差异。

CodeQL 2.27.0 新增的 rust/command-line-injection 查询,目标就是发现这类不受控制的命令行。它把一个过去需要安全工程师手工检查的数据流问题,加入了 Rust 默认安全检查的范围。团队需要注意两件事:第一,新增查询会带来新的告警,告警不等于已经确认存在可利用漏洞;第二,查询无法替代代码审查,业务边界、输入来源和部署环境仍然需要人工判断。

升级后如何处理 Rust 告警

可以按下面的顺序处理:

  1. 先确认输入来源。HTTP 参数、消息队列内容、配置文件和用户上传数据都可能是外部输入,但信任边界取决于实际部署方式。
  2. 再确认执行方式。直接调用固定二进制并把参数作为独立参数传递,与 sh -ccmd /C 或其他 shell 解释器的风险不同。
  3. 最后判断业务约束。即使输入不是公网可控,也要检查是否能被低权限用户、租户或被入侵的上游服务影响。

如果团队有自定义 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 SourceDocker Registry 私有注册表,并确认扫描任务只获得读取查询包所需的权限。不要为了让扫描通过,把一个可以写入源码仓库或发布包的凭据直接交给所有 Runner。

可以把权限拆成三层:

1
2
3
代码仓库:扫描任务读取待分析代码
查询来源:扫描任务读取私有查询和模型包
结果上传:扫描任务写入代码扫描结果

三者不应该共享同一个高权限 token。尤其是自托管 Runner,扫描过程会接触源代码、依赖和分析结果,Runner 被其他任务复用时,还要检查工作目录清理、凭据注入和网络出口策略。

其他变化也可能改变告警基线

2.27.0 并不只针对 ARM64 和 Rust。升级时还应注意这些变化:

  • C/C++ 查询把 PostgreSQL libpqPQexecPQexecParamsPQpreparePQsendQueryPQsendQueryParamsPQsendPrepare 纳入 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 命令行注入查询补上了一个重要的安全检查面,私有注册表配置则让组织规则更容易进入默认扫描流程。

升级时最重要的动作不是立刻追求更少的告警,而是让告警变化可解释。先固定运行环境,再保存版本基线,最后复核新增查询和权限边界,团队才知道这次升级到底发现了什么,也知道哪些问题值得进入修复计划。

参考来源

文章目录
  1. 1. 先看 2.27.0 带来了什么
  2. 2. Linux ARM64 支持,解决的是扫描基础设施问题
  3. 3. Rust 命令行注入查询为什么重要
    1. 3.1. 升级后如何处理 Rust 告警
  4. 4. 私有查询包开始进入 Default Setup
  5. 5. 其他变化也可能改变告警基线
  6. 6. 给安全和平台团队的升级清单
    1. 6.1. 1. 先做架构和安装包矩阵
    2. 6.2. 2. 用基线区分新发现和真实回归
    3. 6.3. 3. 给私有查询包配置最小读取权限
    4. 6.4. 4. 检查自定义模型的升级兼容性
  7. 7. 结语
  8. 8. 参考来源
|