- 静态分析
- SAST
- 应用安全
- 漏洞扫描
- 代码质量
【免费下载链接】codeql
CodeQL: the libraries and queries that power security researchers around the world, as well as code scanning in GitHub Advanced Security
导读
本文基于 CodeQL 开源仓库中 C# 查询包(csharp-qlpack)的0.7.0版本变更记录(csharp/ql/src/change-notes/released/0.7.0.md),系统梳理该版本引入的新安全查询与查询更名事件。通过结合仓库中对应的查询实现(MissingAccessControl.ql、ZipSlip.ql)及其底层库文件,读者将掌握:cs/web/missing-function-level-access-control查询的检测逻辑与适用场景、cs/zipslip查询更名前后的语义变化,以及如何在 CodeQL 中运行、验证这些查询。
版本 0.7.0 概览
0.7.0是 CodeQL C# 查询库演进过程中的一个早期里程碑版本,对应仓库目录 csharp/ql/src/change-notes/released/ 下的发布记录。该版本的核心变更集中在两点:
| 类别 | 变更内容 | 对应查询 ID |
|---|---|---|
| 新增查询 | 新增"缺少函数级访问控制"查询 | cs/web/missing-function-level-access-control |
| 查询更名 | "Zip 解压过程中任意文件写入"(Zip Slip)更名为"归档解压过程中任意文件访问" | cs/zipslip |
这两个变更分别对应 CWE-285/CWE-284/CWE-862(授权缺失)与 CWE-022(路径遍历),是 Web 安全审计中最常见的问题类型。
新增查询:缺失函数级访问控制(cs/web/missing-function-level-access-control)
查询入口与元数据
该查询的入口位于 csharp/ql/src/Security Features/CWE-285/MissingAccessControl.ql,其查询声明头完整定义了查询的元数据:
/** * @name Missing function level access control * @description Sensitive actions should have authorization checks to prevent them from being used by malicious actors. * @kind problem * @problem.severity warning * @security-severity 7.5 * @precision medium * @id cs/web/missing-function-level-access-control * @tags security * external/cwe/cwe-285 * external/cwe/cwe-284 * external/cwe/cwe-862 */ import csharp import semmle.code.csharp.security.auth.MissingFunctionLevelAccessControlQuery from Method m where missingAuth(m) select m, "This action is missing an authorization check."从元数据可以看出:该查询类型为problem(单点问题报告)、严重度为warning、安全严重度 7.5、精度为medium,同时标注了三个 CWE 标签(285 授权不当、284 访问控制不当、862 缺少授权)。查询主体逻辑委托给 MissingFunctionLevelAccessControlQuery.qll,最终对每个Method m判断其是否missingAuth(m),若缺失则在结果中输出 "This action is missing an authorization check."。
底层检测逻辑剖析
查询的判定逻辑完全封装在 MissingFunctionLevelAccessControlQuery.qll 中,其核心可拆解为四个谓词:
1.needsAuth(ActionMethod m)—— 识别需要授权的"敏感动作"
predicate needsAuth(ActionMethod m) { m.isEdit() or m.isAdmin() }该谓词基于ActionMethod类型(位于semmle.code.csharp.frameworks.microsoft.AspNetCore与system.web.UI框架库中),凡是名称或特征命中"编辑(Edit)"或"管理(Admin)"语义的动作方法,都被视为敏感操作,需要存在授权检查。
2.AuthExpr—— 识别授权/认证检查表达式
class AuthExpr extends Expr { AuthExpr() { this.(MethodCall).getTarget() .hasFullyQualifiedName("System.Security.Principal", "IPrincipal", "IsInRole") or this.(PropertyAccess).getTarget() .hasFullyQualifiedName("System.Security.Principal", "IIdentity", ["IsAuthenticated", "Name"]) or this.(MethodCall).getTarget().getName().toLowerCase().matches("%auth%") or this.(PropertyAccess).getTarget().getName().toLowerCase().matches("%auth%") } }AuthExpr通过四种模式识别授权检查:调用IPrincipal.IsInRole判断角色;访问IIdentity.IsAuthenticated或IIdentity.Name判断认证状态;以及通过方法名或属性名包含auth子串(不区分大小写)进行启发式匹配。这种设计既覆盖了标准的 .NET 安全基元,也能捕获自定义的授权 API。
3. 三种授权方式的判定:hasAuthViaCode/hasAuthViaXml/hasAuthViaAttribute
hasAuthViaCode:借助m.getAnAuthorizingCallable()找到方法链上的所有调用者(calls*为传递闭包),判断其中是否存在包含AuthExpr的调用者,即"代码内显式执行了授权逻辑";hasAuthViaXml:解析 Web.config 中System.Web配置节下的<authorization>XML 元素,若存在<deny>子元素,且通过<location path="...">标签或物理路径推导出的路由(getARoute())与方法路由m.getARoute()匹配,则视为已通过声明式配置完成授权;hasAuthViaAttribute:检查方法自身或方法所属类型(含基类,通过getAnUnboundBaseType*向上追溯)是否带有名称匹配%auth%的特征属性(如[Authorize])。
4.missingAuth—— 汇总判定
predicate missingAuth(ActionMethod m) { needsAuth(m) and not hasAuthViaCode(m) and not hasAuthViaXml(m) and not hasAuthViaAttribute(m) and exists(m.getBody().getAChildStmt()) // exclude empty methods }只有当方法"需要授权"但三种授权途径(代码、XML 配置、属性标注)均未命中时,才判定为缺失授权;同时通过exists(m.getBody().getAChildStmt())排除空方法体,避免对抽象或空实现产生误报。
适用场景与典型示例
该查询适用于以下 C# Web 应用场景:
- ASP.NET MVC / Web API 中,名称或语义属于编辑、管理类的 Action 缺少
[Authorize]属性或角色校验; - 自定义授权框架中,敏感接口未调用任何
IsInRole、IsAuthenticated或名称含auth的认证方法; - 声明式授权(Web.config
<authorization>)未覆盖到某敏感路由。
一个典型的安全修复是:为敏感 Action 添加[Authorize]特性(属性名含auth,可被hasAuthViaAttribute识别),或在方法体内调用User.IsInRole("Admin")等授权 API。修复后重新运行查询,对应告警即会消失。
查询更名:Zip Slip 查询语义的正式扩展
更名内容
版本 0.7.0 将查询 "Arbitrary file write during zip extraction ("Zip Slip")"(cs/zipslip)更名为 "Arbitrary file access during archive extraction ("Zip Slip")"。这一更名并非简单的文案调整,而是反映了查询检测能力从"仅关注 ZIP 解压写入"向"覆盖更广泛归档解压文件访问"的语义扩展。
更名后的查询实现
更名后的查询入口位于 csharp/ql/src/Security Features/CWE-022/ZipSlip.ql:
/** * @name Arbitrary file access during archive extraction ("Zip Slip") * @description Extracting files from a malicious ZIP file, or similar type of archive, without * validating that the destination file path is within the destination directory * can allow an attacker to unexpectedly gain access to resources. * @kind path-problem * @id cs/zipslip * @problem.severity error * @security-severity 7.5 * @precision high * @tags security * external/cwe/cwe-022 */ import csharp import semmle.code.csharp.security.dataflow.ZipSlipQuery import ZipSlip::PathGraph from ZipSlip::PathNode source, ZipSlip::PathNode sink where ZipSlip::flowPath(source, sink) select source.getNode(), source, sink, "Unsanitized archive entry, which may contain '..', is used in a $@.", sink.getNode(), "file system operation"该查询的查询 IDcs/zipslip保持不变,但类型为path-problem(路径问题,可展示完整的 source→sink 污点传播链路),严重度为error,精度high。查询通过ZipSlip::flowPath(source, sink)在 taint 流图上寻找从归档条目到文件系统操作的污点路径。
底层污点追踪配置
Zip Slip 的检测逻辑封装在 ZipSlipQuery.qll 中,它是一个标准的TaintTracking::Global配置,包含三类核心组件:
污点源(Source):ArchiveFullNameSource识别对System.IO.Compression.ZipArchiveEntry.FullName属性的访问——该属性返回归档条目的完整路径,可能包含..路径穿越片段。
污点汇聚点(Sink):涵盖多种文件系统操作:
ExtractToFileArgSink:ZipFileExtensions.ExtractToFile扩展方法的destinationFileName参数;FileOpenArgSink:File.Open/File.OpenWrite/File.Create的path参数;FileStreamArgSink/FileInfoArgSink:FileStream、FileInfo构造函数的路径参数。
清洗器(Sanitizer):GetFileNameSanitizer(Path.GetFileName仅提取文件名,剥离路径)、SubstringSanitizer(String.Substring提取单一路径组件)以及StringCheckSanitizer(对String.StartsWith守卫的路径校验,用于确保目标路径位于允许的输出目录内,且不会与Path.Combine的".."未解析特性相混淆)。
这条 source→sink 链路与 ApiSources.qll、ApiSinks.qll 中定义的 API 源/汇模型协同工作,共同支撑查询的污点传播分析。
如何运行与验证 0.7.0 的查询
运行环境
要使用 0.7.0 版本中的查询,需要:
- 安装 CodeQL CLI 或使用 VS Code 的 CodeQL 扩展;
- 使用
codeql database create为 C# 项目创建 CodeQL 数据库(该过程由 csharp 提取器 完成源码到 TRAP 的抽取); - 将查询包定位到本仓库的 csharp/ql 目录。
运行单条查询
codeql query run "csharp/ql/src/Security Features/CWE-285/MissingAccessControl.ql" \ --database=<your-csharp-db> \ --output=missing-access-control.bqrs或一次性运行包含该查询的整套安全套件:
codeql database analyze <your-csharp-db> \ csharp/ql/src --format=sarif-latest --output=results.sarif对于cs/zipslip这类path-problem查询,SARIF 输出中会附带完整的污点传播路径(source → 中间节点 → sink),便于开发者逐跳审查数据流是否真实可达。
测试验证
仓库中 C# 查询的测试位于 csharp/ql/test 目录,使用.qlref文件引用目标查询,.expected文件保存期望输出。修改查询逻辑后,可通过codeql test run回归验证;若期望输出需要更新,可使用codeql test run --update自动重写.expected文件。
版本演进中的后续变更(参考)
作为发布记录,0.7.0的变更在后续版本中持续演进。例如在 0.8.1 版本变更记录 中,cs/web/missing-function-level-access-control查询继续获得改进;完整的变更历史可参考 csharp/ql/src/CHANGELOG.md。如需了解查询在后续版本中的精度提升、误报修复等细节,可逐版本查阅 csharp/ql/src/change-notes/released/ 目录。
小结
CodeQL C# 查询包 0.7.0 通过两个关键变更增强了 C# Web 应用的安全审计能力:
- 新增
cs/web/missing-function-level-access-control:基于needsAuth+ 三种授权途径(代码/XML/属性)的综合判定,识别缺少授权检查的敏感编辑与管理动作,覆盖 CWE-285/284/862; - 更名
cs/zipslip:将查询描述从"ZIP 解压写入"扩展为"归档解压文件访问",配合ZipSlipQuery.qll中覆盖ZipArchiveEntry.FullName源、多种文件系统操作汇点与路径清洗器的污点追踪配置,检测范围更广、语义更准确。
对于安全工程师而言,这两个查询可直接集成进 CI 的codeql database analyze流程,用于 ASP.NET 应用的授权缺失审计与归档解压路径穿越检测。
- 静态分析
- SAST
- 应用安全
- 漏洞扫描
- 代码质量
【免费下载链接】codeql
CodeQL: the libraries and queries that power security researchers around the world, as well as code scanning in GitHub Advanced Security
相关推荐
CodeQL C/C++ 查询包 0.0.11 版本解析:新查询、破坏性变更与精度提升
CodeQL C/C++ 查询包 0.0.11 版本解析:新查询、破坏性变更与精度提升 本指南以 CodeQL 仓库中 cpp/ql/src/change no
静态分析SAST应用安全漏洞扫描代码质量CodeQL 1.20 的 C/C++ 分析改进详解:新查询、查询更新与 QL 库增强
CodeQL 1.20 的 C/C++ 分析改进详解:新查询、查询更新与 QL 库增强 本指南基于 CodeQL 仓库中 change notes/1.20/a
静态分析SAST应用安全漏洞扫描代码质量CodeQL C++ 查询包 0.4.2 更新解读:新增逗号误导性缩进检测与既有查询误报修复
CodeQL C++ 查询包 0.4.2 更新解读:新增逗号误导性缩进检测与既有查询误报修复 导读 本文基于 CodeQL 仓库中 cpp/ql/src/cha
静态分析SAST应用安全漏洞扫描代码质量
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考