
静态分析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 查询集 0.9.0 版本的官方发布说明cpp/ql/src/change-notes/released/0.9.0.md为核心深度剖析该版本的两项关键变更删除重复查询cpp/tainted-format-string-through-global以及新增查询cpp/use-of-string-after-lifetime-ends。读者将理解这两项变更背后的设计动机掌握新查询的检测原理、适用场景与修复方法并学会通过仓库内的查询实现与测试用例验证结论。版本概览一次聚焦的增量更新0.9.0 是 CodeQL C 查询集的增量发布改动集中在两点破坏性变更Breaking Changes删除查询cpp/tainted-format-string-through-global新增查询New Queriescpp/use-of-string-after-lifetime-ends用于检测对即将销毁的字符串调用c_str的悬垂指针问题。两项变更一删一增前者是查询集的收敛与去重后者是安全能力的扩展共同体现了 CodeQL 查询维护中减少噪音、提升精度的一贯取向。破坏性变更移除cpp/tainted-format-string-through-global变更内容0.9.0 版本删除了一条长期存在的查询cpp/tainted-format-string-through-global。发布说明明确给出了删除理由该查询检测到的告警集合是cpp/tainted-format-string查询结果的一个子集属于完全重复删除不会造成任何相关告警丢失。也就是说两条查询在功能上存在包含关系——凡是通过全局变量传播污点触发的格式化字符串问题cpp/tainted-format-string本身已经能够发现专门的through-global变体只是增加了维护成本却没有带来额外的检测价值。源码佐证主查询仍然在岗删除through-global变体后主查询仍保留在仓库中cpp/ql/src/PointsTo/TaintedFormatStrings.ql基于指针分析PointsTo实现污点流分析的格式化字符串查询cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatString.ql对应 CWE-134使用外部控制的格式字符串的安全查询。查询 IDcpp/tainted-format-string继续生效与格式化字符串相关的告警覆盖范围不受影响。在后续版本中cpp/ql/src/CHANGELOG.md 也持续记录了该系列查询的演化读者可沿此路径追溯格式化字符串检测的完整历史。对使用者的影响升级到 0.9.0 后cpp/tainted-format-string-through-global这一查询 ID 将不再可用引用它的自定义查询套件QLS 文件需要同步清理无需担心告警回归被删除查询能发现的全部问题均已在cpp/tainted-format-string的结果中体现若你的工作流中曾按查询 ID 精确筛选结果请改用cpp/tainted-format-string作为过滤条件。新增查询cpp/use-of-string-after-lifetime-ends问题本质临时 std::string 与 c_str 的悬垂指针对std::string对象调用c_str()会返回指向其底层字符数组的指针当该std::string对象被销毁时这个指针立即失效。若指针在对象销毁后仍被使用则属于未定义行为undefined behavior。典型触发场景是函数调用或重载运算符按值返回一个std::string而返回结果没有被及时保存到一个能够延长临时对象生命周期的变量中。根据 C 语言规则这类临时std::string对象在包含它的完整表达式语句结束时即被销毁连同c_str()返回的内存一并失效。最典型的坏味道写法如下取自查询官方示例 UseOfStringAfterLifetimeEndsBad.cpp#include string void work(const char*); // BAD: the concatenated string is deallocated when c_str returns. So work // is given a pointer to invalid memory. void work_with_combined_string_bad(std::string s1, std::string s2) { const char* combined_string (s1 s2).c_str(); work(combined_string); }这里(s1 s2)产生一个临时std::string对其调用c_str()拿到的指针在表达式结束后即悬空work(combined_string)实际读取的是已释放内存。查询实现原理新查询的完整实现位于 cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.ql其元数据声明了关键属性元数据项值含义nameUse of string after lifetime ends查询显示名称kindproblem告警类查询precisionhigh高精度低误报idcpp/use-of-string-after-lifetime-ends稳定查询 IDproblem.severitywarning告警级别为警告security-severity8.8高安全严重度tagsreliability / security / cwe-416 / cwe-664关联 CWE-416释放后使用与 CWE-664生命周期管理不当核心检测逻辑只有短短几行思路非常清晰import cpp import semmle.code.cpp.models.implementations.StdString import Temporaries from Call c where outlivesFullExpr(c) and not c.isFromUninstantiatedTemplate(_) and (c.getTarget() instanceof StdStringCStr or c.getTarget() instanceof StdStringData) and isTemporary(c.getQualifier().getFullyConverted()) select c, The underlying temporary string object is destroyed after the call to c.getTarget() returns.逐条解读其检测条件outlivesFullExpr(c)从 Temporaries 模块导入判定该调用的结果存活超过了完整表达式的边界——即指针被保存下来而非在表达式内立即消费掉。这是区分危险与安全的关键若指针只在本表达式内使用如call(std::string(hello).c_str())临时对象销毁前指针已被消费没有问题。not c.isFromUninstantiatedTemplate(_)排除来自未实例化模板的调用避免在模板定义阶段产生冗余告警保证查询在真实实例化上下文中的精度。c.getTarget() instanceof StdStringCStr or ... StdStringData通过 StdString 模型识别目标函数为std::string的c_str()或data()——两个函数都会返回指向底层缓冲的指针性质完全相同。isTemporary(c.getQualifier().getFullyConverted())检查调用者即被调用c_str/data的对象经过完整类型转换后是一个临时对象。非临时对象如命名变量、延长了生命周期的引用绑定不满足此条件因而不会被误报。从源码结构看该查询是临时对象生命周期分析Temporaries模块与标准库字符串模型StdString模块的组合应用前者回答指针是否逃逸出完整表达式后者回答调用是否作用于临时字符串。两者缺一不可。官方推荐修复方式查询官方文档 UseOfStringAfterLifetimeEnds.qhelp 给出的建议非常直接确保c_str()返回的指针不会活得比底层std::string对象更久。修复示例见 UseOfStringAfterLifetimeEndsGood.cpp先把拼接结果存进一个命名变量以延长生命周期再在需要时调用c_str()#include string void work(const char*); // GOOD: the concatenated string outlives the call to work. So the pointer // obtainted from c_str is valid. void work_with_combined_string_good(std::string s1, std::string s2) { auto combined_string s1 s2; work(combined_string.c_str()); }由于combined_string是具名局部变量其生命周期覆盖整个函数体c_str()返回的指针在work调用期间始终有效。测试用例正反例全覆盖仓库为查询配备了完整的回归测试位于 cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/UseOfStringAfterLifetimeEnds/测试驱动文件test.cpp通过内联注释$ Alert标注每个用例的预期结果期望输出UseOfStringAfterLifetimeEnds.expected记录 13 处告警的精确位置与消息文本测试引用UseOfStringAfterLifetimeEnds.qlref将测试目录绑定到目标查询。测试用例刻意覆盖了c_str()与data()两种 API、直接赋值与条件表达式?:两种传播路径、以及多种逃逸方式形成了一张完整的正反例矩阵被判为 BAD 的场景产生告警场景说明auto s1 std::string(hello).c_str();指针存入变量逃出完整表达式b1 ? std::string(hello).c_str() : 条件表达式结果存入变量s4 std::string(hello).c_str();赋值给既有指针变量v1.push_back(std::string(hello).c_str());指针存入容器v2.push_back({ std::string(hello).c_str() });结构体聚合初始化后存入容器S s5[] { { std::string(hello).c_str() } };数组元素持有悬垂指针return std::string(hello).c_str();函数返回悬垂指针std::string(hello).data()系列data()与c_str()同等对待被判为 GOOD 的场景不产生告警场景说明call(std::string(hello).c_str());指针在完整表达式内立即被消费call_by_value({ std::string(hello).c_str() });按值传入消费即时char c std::string(hello).c_str()[0];立即解引用读取字符s.c_str()s为具名变量底层对象生命周期覆盖指针使用sRef.c_str()引用绑定引用未延长临时生命周期场景之外的安全路径std::string sRefRef std::string(hello);后调用右值引用绑定了临时对象生命周期延长这个测试矩阵直观地展示了查询的判定边界问题不在于对临时字符串调用 c_str而在于c_str 的返回值逃逸了临时对象的生命周期。这也解释了为什么查询被标记为precision high——通过精确的生命周期建模而非简单的语法模式匹配在保持高检出率的同时将误报压到最低。集成状态进入默认安全查询套件新查询并非孤立存在它已被纳入 CodeQL 的默认查询套件。在集成测试的套件期望文件中可以看到其身影例如cpp/ql/integration-tests/query-suite/cpp-code-scanning.qls.expectedcode scanning 默认套件cpp/ql/integration-tests/query-suite/cpp-security-extended.qls.expected安全扩展套件cpp/ql/integration-tests/query-suite/cpp-security-and-quality.qls.expected安全与质量套件这意味着用户在 GitHub Advanced Security 的 code scanning 或codeql database analyze运行标准 C 套件时无需额外配置即可获得该查询的告警。security-severity 8.8的高严重度评级也说明维护者将其视为值得优先修复的可靠性/安全问题。小结CodeQL C 查询集 0.9.0 通过一删一增完成了能力优化删除cpp/tainted-format-string-through-global是查询集的去重瘦身告警覆盖不变维护成本降低新增cpp/use-of-string-after-lifetime-ends将临时 std::string 生命周期这一隐蔽的未定义行为纳入默认检测范围其实现融合了临时对象生命周期分析与标准库字符串模型并配有覆盖 13 处告警、数十种正反例的回归测试精度定位为 high。对于 C 开发者而言理解这条新查询的价值在于建立一条直觉任何对临时字符串对象调用c_str()/data()并保存指针的写法都应当改为先具名保存字符串对象再取指针。这正是 CWE-416释放后使用 与 CWE-664生命周期管理不当在标准库 API 层面的典型体现。后续版本如 1.6.0、1.4.4的变更记录中仍可看到相关查询的持续演进读者可以沿 CHANGELOG 追踪其后续变化。赞分享静态分析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 1.25 C/C 分析变更详解污点追踪库升级、嵌套字段流与默认启用的格式字符串查询CodeQL 1.25 C/C 分析变更详解污点追踪库升级、嵌套字段流与默认启用的格式字符串查询 本文基于 CodeQL 仓库中 change notes静态分析SAST应用安全漏洞扫描代码质量Rust FFI 传递字符串Passing Strings惯用法CString 生命周期、unsafe 最小化与悬垂指针陷阱Rust FFI 传递字符串Passing Strings惯用法CString 生命周期、unsafe 最小化与悬垂指针陷阱 导读 在 Rust 与 C文档教程gh_mirrors/im/im_service API参考开发者必备的接口文档大全gh_mirrors/im/im_service API参考开发者必备的接口文档大全 gh_mirrors/im/im_service 是一个基于 Golan上一篇终极时区智能管理Time Server自动时区检测与转换算法全解析下一篇OBS Studio打造专业级直播录制系统的完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考