CodeQL 诊断查询模板实战:用 QL 枚举数据流 Source 与 Sink,为数据扩展建模铺路 AI 技能AI 插件应用安全网络安全AI 评测【免费下载链接】skillsTrail of Bits Claude Code skills for security research, vulnerability detection, and audit workflows项目地址https://gitcode.com/gh_mirrors/skills8/skills点击查看免费下载本篇技术指南基于 GitHub 加速计划 skills8/skills 仓库中 plugins/static-analysis/skills/codeql/references/diagnostic-query-templates.md 编写讲解如何在 CodeQL 数据扩展Data Extensions建模流程中用语言特定的 QL 诊断查询枚举 CodeQL 当前已识别的数据流 Source 与 Sink。读完本文你将掌握 Python、JavaScript/TypeScript、Go、Java、C/C、C#、Ruby 七种语言的 Source 枚举写法以及五种语言的 Sink 枚举模板、跨语言 Concepts API 差异、Java/C/C# 专属 qlpack 配置并能把查询输出BQRS/CSV接入 create-data-extensions 工作流识别项目自有 API 的建模缺口并生成数据扩展 YAML。诊断查询在 CodeQL 建模流程中的定位CodeQL 的官方库模型覆盖的是通用框架如 Python 的 Django/Flask、JavaScript 的 Express、Java 的 Spring但真实项目的安全相关 API 往往包在项目自有封装里——自定义请求解析、ORM 包装、Shell 封装、文件读写工具——这些是任何随包模型都无法覆盖的。这正是 SKILL.md 反复强调的原则“数据扩展能抓住 CodeQL 漏掉的东西”。诊断查询的作用就是在创建数据扩展之前先搞清楚“CodeQL 现在到底认出了哪些 Source 和 Sink”。在 create-data-extensions.md 工作流中该参考文档是Step 2Query Known Sources and Sinks的直接依据工作流用 Write 工具把这里的模板写入$DIAG_DIR/list-sources.ql和$DIAG_DIR/list-sinks.ql运行后得到sources.csv与sinks.csv再与项目 API 表面交叉比对找出缺口生成扩展。整个过程位于数据库构建之后、正式分析之前属于“先摸底、再补模型”的关键一环。诊断查询的本质是元查询它们不直接报告漏洞而是枚举 CodeQL 内部数据流库中已注册的 Source/Sink 位置输出格式为类型/种类 | 相对路径:起始行号供后续人工或程序化比对使用。Source 枚举查询统一类、分语言导入所有语言的 Source 枚举都使用同一个类RemoteFlowSource差别仅在 import 语句。下表是原文档的完整 Import 参考语言导入类Pythonimport pythonimport semmle.python.dataflow.new.RemoteFlowSourcesRemoteFlowSourceJavaScriptimport javascriptRemoteFlowSourceJavaimport javaimport semmle.code.java.dataflow.FlowSourcesRemoteFlowSourceGoimport goRemoteFlowSourceC/Cimport cppimport semmle.code.cpp.security.FlowSourcesRemoteFlowSourceC#import csharpimport semmle.code.csharp.security.dataflow.flowsources.RemoteRemoteFlowSourceRubyimport rubyimport codeql.ruby.dataflow.RemoteFlowSourcesRemoteFlowSource注意两类语言的差异Python、Java、C#、Ruby、C需要在基础语言库之外额外导入数据流源类所在模块各语言模块名见上表JavaScript 与 Go只需import javascript/import goRemoteFlowSource已包含在基础库内。模板Python其余语言按上表替换导入/** * name List recognized dataflow sources * description Enumerates all locations CodeQL recognizes as dataflow sources * kind problem * id custom/list-sources */ import python import semmle.python.dataflow.new.RemoteFlowSources from RemoteFlowSource src select src, src.getSourceType() | src.getLocation().getFile().getRelativePath() : src.getLocation().getStartLine().toString()模板要点查询元数据头部的kind problem与id custom/list-sources是 CodeQL CLI 运行查询所必需的select输出 Source 的类型名getSourceType()、所在文件的相对路径与起始行号用|分隔便于后续 CSV 化解析。getSourceType() 的语言可用性原文档明确指出getSourceType()仅在 Python、Java、C# 上可用。对于 Go、JavaScript、Ruby 和 C需要将 select 替换为select src, src.getLocation().getFile().getRelativePath() : src.getLocation().getStartLine().toString()即去掉src.getSourceType()片段只保留位置信息。Sink 枚举查询按语言选模板与 Source 统一使用RemoteFlowSource不同Sink 枚举的 Concepts API 在语言间差异显著必须使用与目标语言匹配的正确模板。Java、C/C、C# 需要独立 qlpack原文档强调Java、C/C、C#三种语言没有统一的 Concepts 模块它们的查询直接导入语言库本身因此离开旁边的qlpack.yml将无法编译。在诊断目录下一次性创建该文件将lang替换为java、cpp或csharp然后先执行codeql pack install再运行任何查询# $DIAG_DIR/qlpack.yml — lang is java, cpp, or csharp name: custom/diagnostics version: 0.0.1 dependencies: codeql/lang-all: *对应工作流步骤见 create-data-extensions.mdJava 分支需要创建带codeql/java-all依赖的qlpack.yml并执行codeql pack install。该 pack 同样承载后续数据扩展的部署目标——扩展最终被复制进lang-all包的ext/目录详见 extension-yaml-format.md。概念类参考Python / JavaScript / Go / Ruby这四种语言拥有统一的 Concepts 模块可通过下表直接查找对应概念类与取值方法概念PythonJavaScriptGoRubySQLSqlExecution.getSql()DatabaseAccess.getAQueryArgument()SQL::QueryString(is-a Node)SqlExecution.getSql()命令执行SystemCommandExecution.getCommand()SystemCommandExecution.getACommandArgument()SystemCommandExecution.getCommandName()SystemCommandExecution.getAnArgument()文件访问FileSystemAccess.getAPathArgument()FileSystemAccess.getAPathArgument()FileSystemAccess.getAPathArgument()FileSystemAccess.getAPathArgument()HTTP 客户端Http::Client::Request.getAUrlPart()———解码Decoding.getAnInput()———XML 解析———XmlParserCall.getAnInput()从表内可提炼三条规律文件访问四语言 API 完全一致FileSystemAccess.getAPathArgument()SQL中只有 Go 走“类 is-a Node”路线SQL::QueryString其余三语言都是取方法调用返回的表达式HTTP 客户端、解码、XML 解析属于部分语言的独占概念跨语言移植模板时必须删除不存在的分支。Python 模板六类 Sink/** * name List recognized dataflow sinks * description Enumerates security-relevant sinks CodeQL recognizes * kind problem * id custom/list-sinks */ import python import semmle.python.Concepts from DataFlow::Node sink, string kind where exists(SqlExecution e | sink e.getSql() and kind sql-execution) or exists(SystemCommandExecution e | sink e.getCommand() and kind command-execution ) or exists(FileSystemAccess e | sink e.getAPathArgument() and kind file-access ) or exists(Http::Client::Request r | sink r.getAUrlPart() and kind http-request ) or exists(Decoding d | sink d.getAnInput() and kind decoding) or exists(CodeExecution e | sink e.getCode() and kind code-execution) select sink, kind | sink.getLocation().getFile().getRelativePath() : sink.getLocation().getStartLine().toString()模板通过exists(...)分支为每种概念绑定一个kind字符串如sql-execution、command-executionselect 输出kind | 路径:行号。这里的kind是诊断用标识与后续数据扩展 YAML 中的 sinkModel kind如sql-injection、command-injection语义对应便于在 Step 3 缺口比对时归类。JavaScript / TypeScript 模板三类 Sink/** * name List recognized dataflow sinks * description Enumerates security-relevant sinks CodeQL recognizes * kind problem * id custom/list-sinks-js */ import javascript from DataFlow::Node sink, string kind where exists(DatabaseAccess e | sink e.getAQueryArgument() and kind database-access ) or exists(SystemCommandExecution e | sink e.getACommandArgument() and kind command-execution ) or exists(FileSystemAccess e | sink e.getAPathArgument() and kind file-access ) select sink, kind | sink.getLocation().getFile().getRelativePath() : sink.getLocation().getStartLine().toString()JS 分支只需import javascript即可概念类DatabaseAccess、SystemCommandExecution、FileSystemAccess均随基础库提供。Go 模板含框架专用 SQL 库导入/** * name List recognized dataflow sinks * description Enumerates security-relevant sinks CodeQL recognizes * kind problem * id custom/list-sinks-go */ import go import semmle.go.frameworks.SQL from DataFlow::Node sink, string kind where sink instanceof SQL::QueryString and kind sql-query or exists(SystemCommandExecution e | sink e.getCommandName() and kind command-execution ) or exists(FileSystemAccess e | sink e.getAPathArgument() and kind file-access ) select sink, kind | sink.getLocation().getFile().getRelativePath() : sink.getLocation().getStartLine().toString()Go 需要额外导入semmle.go.frameworks.SQL且 SQL sink 使用instanceof判定SQL::QueryString节点而非方法调用。Ruby 模板四类 Sink/** * name List recognized dataflow sinks * description Enumerates security-relevant sinks CodeQL recognizes * kind problem * id custom/list-sinks-ruby */ import ruby import codeql.ruby.Concepts from DataFlow::Node sink, string kind where exists(SqlExecution e | sink e.getSql() and kind sql-execution) or exists(SystemCommandExecution e | sink e.getAnArgument() and kind command-execution ) or exists(FileSystemAccess e | sink e.getAPathArgument() and kind file-access ) or exists(CodeExecution e | sink e.getCode() and kind code-execution) select sink, kind | sink.getLocation().getFile().getRelativePath() : sink.getLocation().getStartLine().toString()Ruby 导入codeql.ruby.Concepts额外包含XmlParserCall.getAnInput()分支可参考上表概念类自行扩展。Java 模板按漏洞类型划分的 Sink 类Java 不使用 Concepts而是按漏洞类型使用独立的 Sink 类因此需要一次性导入多个安全查询模块。原文档注明此模板需要上文codeql/java-allpack 才能编译。/** * name List recognized dataflow sinks * description Enumerates security-relevant sinks CodeQL recognizes * kind problem * id custom/list-sinks */ import java import semmle.code.java.dataflow.DataFlow import semmle.code.java.security.QueryInjection import semmle.code.java.security.CommandLineQuery import semmle.code.java.security.TaintedPathQuery import semmle.code.java.security.XSS import semmle.code.java.security.RequestForgery import semmle.code.java.security.Xxe from DataFlow::Node sink, string kind where sink instanceof QueryInjectionSink and kind sql-injection or sink instanceof CommandInjectionSink and kind command-injection or sink instanceof TaintedPathSink and kind path-injection or sink instanceof XssSink and kind xss or sink instanceof RequestForgerySink and kind ssrf or sink instanceof XxeSink and kind xxe select sink, kind | sink.getLocation().getFile().getRelativePath() : sink.getLocation().getStartLine().toString()注意 Java 模板的 kind 命名sql-injection、command-injection、path-injection、xss、ssrf、xxe与数据扩展 sinkModel 的 kind 取值extension-yaml-format.md 中的sql-injection、command-injection、path-injection、xss、code-injection、ssrf、unsafe-deserialization几乎一一对应这使诊断输出可以直接指导扩展建模。C/C 模板按函数名匹配C/C 没有 Sink 类而是匹配被调用函数名。同样需要codeql/cpp-allpack。/** * name List recognized dataflow sinks * description Enumerates security-relevant sinks CodeQL recognizes * kind problem * id custom/list-sinks-cpp */ import cpp import semmle.code.cpp.dataflow.DataFlow import semmle.code.cpp.security.CommandExecution import semmle.code.cpp.security.FileAccess import semmle.code.cpp.security.BufferWrite from DataFlow::Node sink, string kind where exists(FunctionCall call | sink.asExpr() call.getAnArgument() and call.getTarget().hasGlobalOrStdName(system) and kind command-injection ) or exists(FunctionCall call | sink.asExpr() call.getAnArgument() and call.getTarget().hasGlobalOrStdName([fopen, open, freopen]) and kind file-access ) or exists(FunctionCall call | sink.asExpr() call.getAnArgument() and call.getTarget().hasGlobalOrStdName([sprintf, strcpy, strcat, gets]) and kind buffer-write ) or exists(FunctionCall call | sink.asExpr() call.getAnArgument() and call.getTarget().hasGlobalOrStdName([execl, execle, execlp, execv, execvp, execvpe, popen]) and kind command-execution ) select sink, kind | sink.getLocation().getFile().getRelativePath() : sink.getLocation().getStartLine().toString()模板采用FunctionCallhasGlobalOrStdName(...)匹配四组危险函数system命令注入、fopen/open/freopen文件访问、sprintf/strcpy/strcat/gets缓冲区写入、execl系列与popen命令执行。若需扩展覆盖面可仿照分支追加更多函数名到hasGlobalOrStdName列表中。C# 模板按漏洞类型划分的 Sink 类C# 与 Java 同思路使用按漏洞划分的 Sink 类。需要codeql/csharp-allpack。/** * name List recognized dataflow sinks * description Enumerates security-relevant sinks CodeQL recognizes * kind problem * id custom/list-sinks-csharp */ import csharp import semmle.code.csharp.dataflow.DataFlow import semmle.code.csharp.security.dataflow.SqlInjectionQuery import semmle.code.csharp.security.dataflow.CommandInjectionQuery import semmle.code.csharp.security.dataflow.TaintedPathQuery import semmle.code.csharp.security.dataflow.XSSQuery from DataFlow::Node sink, string kind where sink instanceof SqlInjection::Sink and kind sql-injection or sink instanceof CommandInjection::Sink and kind command-injection or sink instanceof TaintedPath::Sink and kind path-injection or sink instanceof XSS::Sink and kind xss select sink, kind | sink.getLocation().getFile().getRelativePath() : sink.getLocation().getStartLine().toString()从诊断查询到数据扩展工作流中的完整调用链诊断模板并非孤立存在它们被 create-data-extensions.md 工作流按固定顺序消费1. 数据库与语言选定Step 2a$DB_NAME可由父级 skill 预先设置否则用 scripts/find_databases.sh 发现再通过codeql resolve database --formatjson读取语言。关键陷阱codeql database create会在构建完成前就写入codeql-database.yml标记文件中途被杀死的构建会留下一个“假数据库”——若选中它list-sources.ql与list-sinks.ql将返回空结果Step 3 的“未发现缺口”提前退出会把覆盖不足误报为覆盖充分。这也是 SKILL.md 强调“数据库质量不可妥协”的原因之一构建后应运行 scripts/check_db_quality.py 把关。2. 写入查询文件Step 2b / 2c用 Source 模板按$CODEQL_LANG选取正确 import 块写入$DIAG_DIR/list-sources.ql用对应语言的 Sink 模板写入$DIAG_DIR/list-sinks.qlJava 额外创建$DIAG_DIR/qlpack.ymlcodeql/java-all依赖并执行codeql pack install。3. 运行查询并解码Step 2dcodeql query run --database$DB_NAME --output$DIAG_DIR/sources.bqrs -- $DIAG_DIR/list-sources.ql codeql bqrs decode --formatcsv --output$DIAG_DIR/sources.csv -- $DIAG_DIR/sources.bqrs codeql query run --database$DB_NAME --output$DIAG_DIR/sinks.bqrs -- $DIAG_DIR/list-sinks.ql codeql bqrs decode --formatcsv --output$DIAG_DIR/sinks.csv -- $DIAG_DIR/sinks.bqrscodeql query run产出二进制 BQRScodeql bqrs decode --formatcsv转为可读 CSV。之后读取两份 CSV按 Source 类型与 Sink 种类汇总计数向用户汇报。4. 识别缺口Step 3将项目 API 表面HTTP 请求处理、数据库层、命令执行、文件操作、模板渲染、反序列化、HTTP 客户端、净化器、透传封装与sources.csv/sinks.csv交叉比对。一个 API 属于“缺失”当且仅当它处理用户输入却未出现在sources.csv或执行危险操作却未出现在sinks.csv或透传污染数据却没有 summary 模型。例如自定义请求解析函数未在 CSV 中出现就应建模为sourceModelkind:remote与诊断模板中RemoteFlowSource枚举的源类别直接呼应。5. 生成扩展并验证Step 4 / Step 5缺口确认后在$OUTPUT_DIR/extensions/生成sources.yml、sinks.yml、summaries.ymlYAML 列定义见 extension-yaml-format.md再以“基线分析 vs 带扩展分析”对比找差距数验证。若带扩展的发现数未增加需检查扩展加载-vvv标志、预编译 pack 部署方案、JavaTrue/False大小写、列值准确性——这些排查项正是诊断查询结果与扩展建模之间的闭环校验。实践要点与常见坑Source 枚举的类型语义与威胁模型相关诊断查询枚举的是RemoteFlowSource对应 threat-models.md 中默认激活的remote源类别HTTP 请求、网络输入。若审计 CLI 工具、容器环境或二次注入场景需通过--threat-model local、--threat-model environment、--threat-model database等标志扩展源集合再据实扩大枚举范围。select 输出格式服务于 CSV 化类型 | 相对路径:行号的分隔符布局与codeql bqrs decode --formatcsv的输出天然衔接不要在模板中随意改动列顺序否则 Step 3 的比对脚本逻辑需同步调整。每种语言各建一份诊断查询Source 查询虽共用RemoteFlowSource类但 import 块不同Sink 查询更是语言专属。多语言仓库应分别在$DIAG_DIR下按语言生成list-sources.ql/list-sinks.qlJava/C/C# 各配一个qlpack.yml。零结果不可直接视为“安全”结合 SKILL.md 的 Success Criteria空枚举结果可能是数据库提取失败、模型缺失或 suite 过滤所致应先用 scripts/check_db_quality.py 与 scripts/verify_query_suite.py 排除数据库与查询套件问题再谈建模缺口。语言构建差异决定诊断可行性诊断查询必须运行在已构建好的数据库之上。可参考 language-details.md 中 Python/JS/Ruby 无需构建、Go/Java/C/C# 需要构建命令的区分——若数据库本身不完整如编译型语言退化为--build-modenoneSource/Sink 枚举结果将严重失真。通过上述模板与工作流你可以精确回答“CodeQL 在这个项目里认出了哪些 Source 和 Sink”并据此为项目自有 API 补齐数据扩展模型最终提升 run-analysis 工作流 的漏洞发现覆盖率。赞分享AI 技能AI 插件应用安全网络安全AI 评测【免费下载链接】skillsTrail of Bits Claude Code skills for security research, vulnerability detection, and audit workflows项目地址https://gitcode.com/gh_mirrors/skills8/skills点击查看免费下载相关推荐Buzz 离线语音转文字安装教程4 步完成首次转录Buzz 离线语音转文字安装教程4 步完成首次转录 这篇文章帮你在自己电脑上装好 Buzz把音视频离线转成文字。正确做法按芯片架构从官方渠道下载安装包放AI 技能AI 插件应用安全网络安全AI 评测CodeQL C 数据流源扩展将 System.Console.Read 系列方法建模为本地用户输入CodeQL C 数据流源扩展将 System.Console.Read 系列方法建模为本地用户输入 导读本篇以 CodeQL 仓库中 C 语言包的一则变更静态分析SAST应用安全漏洞扫描代码质量FastDepth项目架构分析数据加载、模型训练与评估流程深度解析FastDepth项目架构分析数据加载、模型训练与评估流程深度解析 FastDepth是一个专为嵌入式系统设计的 快速单目深度估计 项目由MIT研究团队开发前端静态站点Web框架上一篇移动硬盘在 Mac 上只能看不能写这个免费开源工具让我一分钱没花下一篇3分钟搞定Mac NTFS读写免费开源工具Free-NTFS-for-Mac完整实测创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考