
静态分析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 查询包 1.0.1 版本的官方变更说明展开深入解析其中唯一一条分析改进cpp/dangerous-function-overflow查询在gets函数参数个数不为 1 时不再产生误报。读者将理解该查询的检测目标与实现原理、误报产生的根源、修复后的判定逻辑以及仓库中配套的测试用例如何验证这一行为。一、变更说明原文与定位CodeQL C 查询包 1.0.1 的官方变更说明文件位于 cpp/ql/src/change-notes/released/1.0.1.md全文如下## 1.0.1 ### Minor Analysis Improvements * The cpp/dangerous-function-overflow no longer produces a false positive alert when the gets function does not have exactly one parameter.这是一条典型的 Minor Analysis Improvements次要分析改进条目核心信息可以拆解为三点受影响查询cpp/dangerous-function-overflow变更行为不再产生误报false positive alert触发条件当gets函数不是恰好一个参数时does not have exactly one parameter。该条目同样被汇总进了包级变更日志 cpp/ql/src/CHANGELOG.md 的## 1.0.1一节与 1.0.0 的 Breaking ChangesCodeQL 包管理正式可用、所有 GitHub 产出的 CodeQL 包版本号统一提升至 1.0.0构成版本上下文的连续记录。这意味着 1.0.1 是包版本体系升到 1.0.x 后的第一个分析改进版本。二、查询背景为什么检测getscpp/dangerous-function-overflow的元数据定义在 cpp/ql/src/Security/CWE/CWE-676/DangerousFunctionOverflow.ql 的头部注释中/** * name Use of dangerous function * description Use of a standard library function that does not guard against buffer overflow. * kind problem * problem.severity error * security-severity 10.0 * precision very-high * id cpp/dangerous-function-overflow * tags reliability * security * external/cwe/cwe-242 * external/cwe/cwe-676 */要点包括查询 ID 为cpp/dangerous-function-overflow问题严重级别为 error安全严重性评分为 10.0精度为 very-high同时关联 CWE-242Use of Inherently Dangerous Function与 CWE-676Use of Potentially Dangerous Function两类弱点。配套的说明文档 cpp/ql/src/Security/CWE/CWE-676/DangerousFunctionOverflow.qhelp 解释了检测动机gets不提供任何限制读取数据量的机制因此在事先不知道输入内容的情况下无论缓冲区多大都无法安全使用gets正是 1988 年互联网蠕虫Morris worm所利用的漏洞之一。该文档给出的修复建议是用fgets并显式指定最大拷贝长度。仓库中的示例 cpp/ql/src/Security/CWE/CWE-676/DangerousFunctionOverflow.c 展示了两种写法#define BUFFERSIZE (1024) // BAD: using gets void echo_bad() { char buffer[BUFFERSIZE]; gets(buffer); printf(Input was: %s\n, buffer); } // GOOD: using fgets void echo_good() { char buffer[BUFFERSIZE]; fgets(buffer, BUFFERSIZE, stdin); printf(Input was: %s\n, buffer); }两种写法读取的输入量相同但fgets通过长度参数把写入量限制在缓冲区大小以内从根本上杜绝溢出。三、修复后的查询实现参数个数约束1.0.1 变更对应的实现就在上述查询文件中。当前仓库中的查询主体逻辑如下见 DangerousFunctionOverflow.qlimport cpp from FunctionCall call, Function target where call.getTarget() target and target.hasGlobalOrStdName(gets) and target.getNumberOfParameters() 1 select call, gets does not guard against buffer overflow.修复的关键在于where子句的最后一行条件target.getNumberOfParameters() 1。该条件的语义可以从 CodeQL C 标准库的谓词定义理解call.getTarget()取调用表达式解析到的目标函数Function实体并与target变量绑定target.hasGlobalOrStdName(gets)要求该函数具有全局或std命名空间下的gets名称即认定它是标准库意义上的getstarget.getNumberOfParameters() 1要求目标函数的参数个数恰好为 1。标准 C 库中的gets原型为char *gets(char *s);恰好一个参数。当源码中出现多参数版本的gets声明非标准扩展、头文件中的错误原型或与gets同名的自定义函数时getNumberOfParameters()不等于 1该调用将不再被报告。从当前实现可以看出1.0.1 正是通过把恰好一个参数作为判定前提将此类非标准形态的调用排除在告警之外从而消除误报。四、误报场景与修复逻辑剖析gets是缓冲区溢出风险极高、但标准签名极其简单单参数的库函数。误报的产生场景可以结合查询条件推断若代码库中出现了带多个参数的gets声明例如某些嵌入式平台或旧式编译器提供扩展签名调用方虽名为gets但行为并非标准gets未必直接造成无界写入修复前查询仅依据hasGlobalOrStdName(gets)匹配函数名对这类调用一律告警形成误报修复后查询同时要求参数个数恰为 1只有真正符合标准签名的gets调用才会触发告警。需要说明的是仓库只保留了修复后的查询文件因此修复前实现的具体写法无法直接核对但从变更说明与当前源码的对应关系可以明确推断参数个数检查正是本次改进引入的判定条件这也与变更说明does not have exactly one parameter的措辞逐字吻合。五、测试用例如何锁定修复行为仓库为 CWE-676 目录下的查询提供了完整的测试基准qlref 与 expected 文件可以验证修复后的告警行为。在 cpp/ql/test/query-tests/Security/CWE/CWE-676/semmle/PotentiallyDangerousFunction/test.c 中被测代码先按标准单参数签名声明gets再发起两次调用char *gets(char *s); void testGets() { char buf1[1024]; char *buf2 malloc(1024); char *s; gets(buf1); // $ Alert[cpp/dangerous-function-overflow] // BAD: use of gets s gets(buf2); // $ Alert[cpp/dangerous-function-overflow] // BAD: use of gets }其中$ Alert[cpp/dangerous-function-overflow]是测试注解声明这两处调用应产生告警。对应的期望输出 DangerousFunctionOverflow.expected 精确到行列| test.c:42:2:42:5 | call to gets | gets does not guard against buffer overflow. | | test.c:43:6:43:9 | call to gets | gets does not guard against buffer overflow. |测试同时覆盖了多种目标形态同一 CWE-676 测试目录下还有PotentiallyDangerousFunction相关用例cpp/ql/test/query-tests/Security/CWE/CWE-242/semmle/tests/tests.cpp 中则验证了gets作用于普通数组与 typedef 数组MyCharArray时均能告警char *gets(char *s); typedef char MyCharArray[10]; void test3(char c, int val, char *str) { char buffer10[10]; MyCharArray myBuffer10; gets(buffer10); // $ Alert[cpp/dangerous-function-overflow] // BAD: use of gets gets(myBuffer10); // $ Alert[cpp/dangerous-function-overflow] // BAD: use of gets ... }这些用例共同说明在标准单参数声明下查询仍按 very-high 精度稳定报出Use of dangerous function而一旦gets签名偏离标准形态参数个数条件将把调用过滤掉——这正是 1.0.1 消除误报后保留的判定边界。六、变更对使用者的实际影响对使用 CodeQL C 查询包 1.0.1 及后续版本的开发者而言本次变更意味着告警口径更精确只有符合标准char *gets(char *s)签名的调用才会被标记为危险函数使用误报显著减少带多参数gets声明非标准形态的代码不再被误报扫描结果更可信检测能力不变真正调用标准gets的代码仍会以 error 级别告警修复建议改用fgets并指定长度依然有效可在本地复核通过仓库中的测试基准test.c、tests.cpp与对应的.expected、.qlref文件运行 CodeQL 测试框架即可验证上述行为也可直接阅读 DangerousFunctionOverflow.ql 确认判定逻辑。七、小结CodeQL C 包 1.0.1 虽只包含一条 Minor Analysis Improvements却精准刻画了安全查询研发中减少误报而不牺牲检测能力的典型做法为cpp/dangerous-function-overflow的标准库函数匹配增加参数个数约束使gets告警严格对齐其真实危险形态。结合 变更说明、查询实现、qhelp 文档 与多层测试基准开发者既可以快速理解该版本的行为变化也能以此为样本掌握 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点击查看免费下载相关推荐ArchiveBox Crawl REST API 深度解析/api/v1/crawls 端点、请求模式与实现细节ArchiveBox Crawl REST API 深度解析/api/v1/crawls 端点、请求模式与实现细节 ArchiveBox 的 archiveb静态分析SAST应用安全漏洞扫描代码质量5 步部署 AzerothCore魔兽世界私服从零跑起来5 步部署 AzerothCore魔兽世界私服从零跑起来 一个周末把一台 3.3.5 的魔兽世界私服拉起来不用买服务器、不用手搓环境AzerothCor静态分析SAST应用安全漏洞扫描代码质量CodeQL C 5.4.0 变更解析SSA 数据流 API 公开化与 cpp/overrun-write 误报削减CodeQL C 5.4.0 变更解析SSA 数据流 API 公开化与 cpp/overrun write 误报削减 导读 本文基于 CodeQL 仓库中静态分析SAST应用安全漏洞扫描代码质量上一篇Apache Superset 企业级数据可视化平台架构解析与最佳实践下一篇Black Hat Go网络编程高性能TCP扫描器优化技巧创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考