CodeQL C/C++ 静态缓冲区溢出检测:从 `cpp/static-buffer-overflow` 的精度升级看安全查询工程化

发布时间:2026/9/27 7:05:03
CodeQL C/C++ 静态缓冲区溢出检测:从 `cpp/static-buffer-overflow` 的精度升级看安全查询工程化 静态分析SAST应用安全漏洞扫描代码质量【免费下载链接】codeqlCodeQL: the libraries and queries that power security researchers around the world, as well as code scanning in GitHub Advanced Security项目地址https://gitcode.com/gh_mirrors/co/codeql点击查看免费下载本篇文章围绕 CodeQL 仓库cpp/old-change-notes/2021-09-27-overflow-static.md这条变更记录展开系统讲解 C/C 静态数组越界问题cpp/static-buffer-overflow的检测原理、检测范围、精调度机制以及该查询从 2021 年 5 月到 9 月经历的三轮演进降误报 → 扩大变长字段识别 → 精度升级为 high 并默认启用。读完本文你将掌握该查询在源码中的定位与实现要点、precision与security-severity元数据如何驱动 CodeQL 的默认启用策略以及如何通过测试套件与ConfigurationTestFile机制理解其检测边界。变更记录解读一次默认开启的里程碑cpp/old-change-notes/2021-09-27-overflow-static.md是 2021 年 9 月 27 日发布的 CodeQL 变更说明全文如下lgtm,codescanning * Increase precision to high for the Static buffer overflow query (cpp/static-buffer-overflow). This means the query is run and displayed by default on Code Scanning and LGTM.短短三行内容蕴含了 CodeQL 安全查询发布流程中的两个关键机制标签lgtm,codescanning表示该变更同时影响 LGTM.com 与 GitHub Code Scanning 两个平台。precision从既有等级提升到high触发 CodeQL 的默认查询集包含逻辑使该查询无需用户显式配置即可在 Code Scanning 和 LGTM 上运行并展示结果。在仓库中该查询的实体文件为 cpp/ql/src/Critical/OverflowStatic.ql其头部元数据正体现了这次升级的最终状态/** * name Static array access may cause overflow * description Exceeding the size of a static array during write or access operations * may result in a buffer overflow. * kind problem * problem.severity warning * security-severity 9.3 * precision high * id cpp/static-buffer-overflow * tags reliability * security * external/cwe/cwe-119 * external/cwe/cwe-131 */其中precision high对应 2021-09-27 这次变更的落点。在 CodeQL 中precision反映查询的误报率水平是查询能否进入默认启用列表的核心依据。problem.severity warning与security-severity 9.3表示该问题按安全严重性评级高达 9.3属于高危告警对应 CWE-119内存缓冲区边界内操作限制不当与 CWE-131缓冲区大小计算错误。kind problem表示这是一条问题类查询会生成告警条目而非路径类结果。查询是什么静态数组越界的三类检测场景结合 OverflowStatic.ql 的源码cpp/static-buffer-overflow并非单一规则而是由三个谓词共同构成的三类检测场景场景对应谓词典型触发代码循环中数组下标越界overflowOffsetInLoopfor (i 0; i N; i) buf[i]且N超过buf大小传入错误缓冲区大小的库函数调用wrongBufferSizestrncpy(buf, s, SIZE)而SIZE sizeof(buf)常量下标直接越界访问outOfBoundsbuf[5]而buf只有 5 个元素场景一循环计数器驱动越界overflowOffsetInLoop通过ClassicForLoop检查经典三段式for循环循环上限loop.limit() bufaccess.bufferSize()循环计数器loop.counter()恰好是数组下标bufaccess.getArrayOffset()区间分析SimpleRangeAnalysis未给出更小的上界且上限未被widenednot upperBoundMayBeWidened。命中时输出形如Potential buffer-overflow: counter i 3 but buffer1 has 3 elements.其实际测试期望见 cpp/ql/test/query-tests/Critical/OverflowStatic/OverflowStatic.expected|| test.cpp:19:3:19:12 | access to array | Potential buffer-overflow: counter i 3 but buffer1 has 3 elements. || test.cpp:20:3:20:12 | access to array | Potential buffer-overflow: counter i 3 but buffer2 has 3 elements.场景二缓冲区大小参数与声明不符wrongBufferSize维护了一张常见 C 库函数签名表谓词bufferAndSizeFunction精确记录哪个参数是缓冲区、哪个参数是大小函数缓冲区参数索引大小参数索引read12fgets01strncpy02strncat02memcpy02memmove02snprintf01vsnprintf01检测逻辑为目标缓冲区是静态数组staticBuffer(call.buffer(), buf, bufsize)且声明大小bufsize小于调用中实际传入的大小statedSize。大小实参的取值同时来自数据流DataFlow::localExprFlow与区间分析的上界upperBound并取两者最小值以保证结果可靠。典型误报示例来自查询自带的示例文件 OverflowStatic.cpp#define SIZE 30 int f(char * s) { char buf[20]; //buf not set to use SIZE macro strncpy(buf, s, SIZE); //wrong: copy may exceed size of buf for (int i 0; i SIZE; i) { //wrong: upper limit that is higher than array size cout array[i]; } }场景三常量下标直接越界outOfBounds直接比对数组访问的常量下标与数组大小并做了两个严谨的边界处理当access size时如果该访问是buf[size]取地址或offsetof的一部分则不告警——因为取越界元素地址取地址后不解引用与offsetof是合法惯用法只有access size才无条件告警。对应测试期望|| test.c:14:9:14:13 | access to array | Potential buffer-overflow: xs has size 5 but xs[5] may be accessed here. || test.c:15:9:15:13 | access to array | Potential buffer-overflow: xs has size 5 but xs[6] may be accessed here.精调度precision如何决定默认启用CodeQL 查询元数据中的precision是对查询可信度的官方评级等级从低到高通常为low/medium/high/very-high。high表示该查询具有较低的误报率足以进入默认启用的安全查询集。本次 2021-09-27 的变更正是将 OverflowStatic.ql 的precision提升为high其直接后果写在了变更说明中该查询会在 Code Scanning 和 LGTM 上默认运行并展示结果。换言之在精度升级前cpp/static-buffer-overflow属于需要用户主动加入查询集的查询升级后C/C 用户只要开启 CodeQL 默认安全查询即可自动获得该检查。在仓库中C/C 默认启用查询集的配置位于 cpp/config/suites 目录下的查询套件文件无扩展名的 suite 文件CodeQL 会依据precision、security-severity等元数据筛选纳入默认集的问题类查询。演进路径2021 年内的三次迭代cpp/static-buffer-overflow在 2021 年内经历了一个典型的从可用到可信演进过程旧变更记录忠实记录了每一步第一步2021-05-18减少误报。变更 2021-05-18-static-buffer-overflow.md 记载该查询已被改进以产生更少的误报标签仅为lgtm说明当时主要在 LGTM 平台验证。第二步2021-09-13扩展变长字段识别。变更 2021-09-13-overflow-static.md 说明memberMayBeVarSize谓词现在会考虑更多变长字段如 flexible array member 等从而进一步减少误报。在 OverflowStatic.ql 中staticBufferBase通过not memberMayBeVarSize(_, v)将可能属于变长结构的变量排除在静态缓冲区判定之外。第三步2021-09-27精度升级为 high 并默认启用。即本篇文章的主题文档标签升级为lgtm,codescanning两个平台同步生效。此外在 cpp/ql/src/change-notes/released/1.3.2.md 与 cpp/ql/src/CHANGELOG.md 中还能看到后续工程化细节cpp/static-buffer-overflow等查询不再对CMake 构建配置测试生成的临时文件产生告警这类文件由ConfigurationTestFile谓词识别并在查询末尾统一排除not error.getFile() instanceof ConfigurationTestFile // elements in files generated during configuration are likely false positives检测边界与防误报设计从源码可以总结出该查询刻意控制的几个边界理解这些边界有助于准确解读告警只针对字符数组staticBufferBase要求数组基类型为CharType避免对数值数组的误报同时要求访问必须被求值not access.isUnevaluated()排除sizeof等不求值语境。排除strcmp宏展开BufferAccess构造器显式排除strcmp宏实现中看起来危险但实际受控的访问。排除死代码reachable(this)保证只分析可达路径。排除变长结构成员memberMayBeVarSize排除 flexible array 等场景这也是 2021-09-13 变更的落点。排除 CMake 配置测试文件ConfigurationTestFile机制2021 年 1.3.2 版落实。offsetof与取地址例外access size时不告警除非访问被解引用。测试方面该查询拥有完整的回归测试体系查询引用文件 cpp/ql/test/query-tests/Critical/OverflowStatic/OverflowStatic.qlref 指向Critical/OverflowStatic.ql并使用InlineExpectationsTestQuery.ql做内联期望校验期望文件 cpp/ql/test/query-tests/Critical/OverflowStatic/OverflowStatic.expected 覆盖了test.c常量越界、test2.c大小实参大于缓冲区与test.cpp循环越界 错误大小参数三类用例安全套件路径下还挂有 SAMATE 参考用例与semmle/tests两套独立测试cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverflowStatic.qlref、cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowStatic.qlref。实践建议如何用这条查询排查静态缓冲区溢出在 C/C 项目中启用 CodeQL 后cpp/static-buffer-overflow已随默认安全查询集运行。若需人工核对告警建议按以下顺序排查循环越界类告警检查循环上限与数组声明大小是否一致注意#define SIZE 30与char buf[20]这类宏尺寸与局部声明脱节的典型模式参见 OverflowStatic.cpp。错误大小参数类告警核对strncpy、memcpy、snprintf等调用传入的 size 实参是否超过目标缓冲区实际大小。常量下标类告警检查buf[N]中N是否等于数组长度有效下标应为0..N-1。同时注意该查询的适用范围它针对静态声明的、大小可静态确定的字符数组对于堆分配缓冲区、std::vector等动态容器以及变长结构成员需要配合 CodeQL 的 CWE-119 套件中其他查询如 cpp/ql/src/Security 下的相关数据流查询一起使用。小结从 2021 年 5 月的降误报到 9 月 13 日的变长字段识别扩展再到 9 月 27 日将cpp/static-buffer-overflow的precision提升至high并默认启用这条查询的演进完整展示了 CodeQL 安全查询的发布准则先通过测试与误报控制证明可信度再以precision元数据进入默认查询集。理解这一机制既能帮你更准确地解读 C/C 项目的 CodeQL 扫描结果也能为你在 CodeQL 中自研安全查询的转正流程提供直接参考。赞分享静态分析SAST应用安全漏洞扫描代码质量【免费下载链接】codeqlCodeQL: the libraries and queries that power security researchers around the world, as well as code scanning in GitHub Advanced Security项目地址https://gitcode.com/gh_mirrors/co/codeql点击查看免费下载相关推荐CodeQL C/C 静态缓冲区溢出查询优化memberMayBeVarSize 变长结构体判定与误报治理CodeQL C/C 静态缓冲区溢出查询优化 memberMayBeVarSize 变长结构体判定与误报治理 导读 本文以 CodeQL 仓库中 C/C静态分析SAST应用安全漏洞扫描代码质量CodeQL C 命令注入检测深度解析cpp/command-line-injection 查询的高精度化演进CodeQL C 命令注入检测深度解析 cpp/command line injection 查询的高精度化演进 本文围绕 CodeQL C 查询库中静态分析SAST应用安全漏洞扫描代码质量CodeQL C 安全查询实战cpp/toctou-race-condition 时间检查与使用竞态检测及其改进CodeQL C 安全查询实战 cpp/toctou race condition 时间检查与使用竞态检测及其改进 本文围绕 CodeQL C 查询库静态分析SAST应用安全漏洞扫描代码质量上一篇Polar Python SDK 快速接入指南用官方客户端连接 Polar 计费平台下一篇G-Helper终极指南让你的华硕笔记本性能飙升的免费神器创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考