关于 variant-analysis
面向授权防御性安全研究的漏洞变体分析指南,帮助安全人员从已知漏洞提炼模式,并用 CodeQL、Semgrep 等工具在代码库中查找相似问题。
主要功能
- 01分析种子漏洞模式
- 02编写 CodeQL 数据流查询
- 03创建 Semgrep 匹配规则
- 04跨仓库查找变体
- 05分类并报告发现
适用场景
- 01在自有代码中追踪已知漏洞
- 02CVE 披露后排查同类问题
- 03对多个相关仓库进行安全审查
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ oimiragieo/ agent-studio --skill variant-analysis安装后在 Claude Code 中输入/variant-analysis确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
commands/variant-analysis.mdhooks/post-execute.cjspre-execute.cjsreferences/research-requirements.mdrules/variant-analysis.mdschemas/input.schema.jsonoutput.schema.jsonscripts/main.cjstemplates/implementation-template.md详细介绍
变体分析
安全声明
仅限授权使用:这些技能仅用于防御性安全分析和经授权的研究:
- 经书面许可的安全评估
- 在自有代码库中主动发现漏洞
- CVE 报告后进行事后变体搜寻
- 遵循适当披露流程的安全研究
- 在受控环境中用于教育目的
绝不可用于:
- 未经授权扫描系统
- 开发用于未授权用途的漏洞利用程序
- 绕过安全控制
- 任何非法活动
步骤 1:种子漏洞分析
从已知漏洞(CVE、缺陷报告或代码模式)入手:
提取漏洞模式
- 识别缺陷类别:这属于哪种漏洞?(SQL 注入、XSS、缓冲区溢出、TOCTOU 等)
- 识别来源:不可信数据从何处进入?(用户输入、网络、文件、环境)
- 识别接收点:数据会在何处造成危害?(SQL 查询、HTML 输出、内存写入、系统调用)
- 识别缺失的净化操作:来源与接收点之间缺少了什么检查或转换?
- 抽象模式:将模式推广到具体实例之外
种子分析示例
CVE-2024-XXXX: SQL Injection in user search
- Bug class: CWE-089 (SQL Injection)
- Source: HTTP request parameter `q`
- Sink: String concatenation into SQL query
- Missing: Parameterized query or input sanitization
- Pattern: request.param → string concat → db.query()
步骤 2:模式泛化
将种子转换为查询模式:
抽象层级
| 层级 | 说明 | 示例 |
|---|---|---|
| 精确 | 同一函数、同一文件 | searchUsers(req.query.q) |
| 局部 | 同一模式、不同函数 | 任意 db.query("..."+userInput) |
| 结构 | 相同数据流形态 | 任意未经过净化的来源到接收点的数据流 |
| 语义 | 相同缺陷类别、任意语法 | 任意 SQL 注入变体 |
CodeQL 模式模板
/**
* @name Variant of CVE-XXXX: [description]
* @description Finds code structurally similar to [seed vulnerability]
* @kind path-problem
* @problem.severity error
* @security-severity 8.0
* @precision high
* @id js/variant-cve-xxxx
* @tags security
* external/cwe/cwe-089
*/
import javascript
import DataFlow::PathGraph
class UntrustedSource extends DataFlow::Node {
UntrustedSource() {
// Define sources: HTTP parameters, request body, etc.
this = any(Express::RequestInputAccess ria).flow()
}
}
class VulnerableSink extends DataFlow::Node {
VulnerableSink() {
// Define sinks: string concatenation in SQL context
exists(DataFlow::CallNode call |
call.getCalleeName() = "query" and
this = call.getArgument(0)
)
}
}
class VariantConfig extends DataFlow::Configuration {
VariantConfig() { this = "VariantConfig" }
override predicate isSource(DataFlow::Node source) {
source instanceof UntrustedSource
}
override predicate isSink(DataFlow::Node sink) {
sink instanceof VulnerableSink
}
override predicate isBarrier(DataFlow::Node node) {
// Known sanitizers that prevent the vulnerability
node = any(DataFlow::CallNode c |
c.getCalleeName() = ["escape", "sanitize", "parameterize"]
).getAResult()
}
}
from VariantConfig config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select sink.getNode(), source, sink,
"Potential variant of CVE-XXXX: untrusted data flows to SQL query without sanitization."
Semgrep 模式模板
rules:
- id: variant-cve-xxxx-sql-injection
message: >
Potential variant of CVE-XXXX: User input flows into SQL query
via string concatenation without parameterization.
severity: ERROR
languages: [javascript, typescript]
metadata:
cwe:
- CWE-089
confidence: HIGH
impact: HIGH
category: security
technology:
- express
- node.js
references:
- https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-XXXX
patterns:
- pattern-either:
- pattern: |
$DB.query("..." + $USERINPUT + "...")
- pattern: |
$DB.query(`...${$USERINPUT}...`)
- pattern: |
$QUERY = "..." + $USERINPUT + "..."
...
$DB.query($QUERY)
- pattern-not:
- pattern: |
$DB.query($QUERY, [...])
fix: |
$DB.query($QUERY, [$USERINPUT])
步骤 3:发现变体
运行分析
# CodeQL variant scan
codeql database analyze codeql-db \
--format=sarifv2.1.0 \
--output=variant-results.sarif \
./variant-queries/
# Semgrep variant scan
semgrep scan \
--config=./variant-rules/ \
--sarif --output=variant-semgrep.sarif
# Cross-repo CodeQL scan (GitHub)
codeql database analyze codeql-db-repo-1 codeql-db-repo-2 \
--format=sarifv2.1.0 \
--output=cross-repo-variants.sarif \
./variant-queries/
手动搜索模式
当自动化工具遗漏变体时,使用手动搜索:
# Search for the syntactic pattern
grep -rn "db\.query.*\+" --include="*.js" --include="*.ts" .
# Search for the function call pattern
grep -rn "\.query\s*(" --include="*.js" --include="*.ts" . | grep -v "parameterized\|escape\|sanitize"
# AST-based search with ast-grep
sg -p 'db.query("..." + $X)' --lang js
步骤 4:变体分类
对各个变体进行分诊
对每个发现的实例进行分类:
| 因素 | 问题 | 对优先级的影响 |
|---|---|---|
| 可达性 | 攻击者能否触达此代码路径? | 可达时为严重 |
| 可利用性 | 能否利用此漏洞? | 可利用时为严重 |
| 影响 | 利用漏洞会造成什么损害? | 根据 CIA 三要素评估 |
| 置信度 | 有多大把握确认这是一个真阳性? | 高/中/低 |
| 相似度 | 与种子的结构相似度有多高? | 越高,置信度越高 |
跟踪变体族
## Variant Family: CWE-089 SQL Injection
### Seed: CVE-XXXX (src/api/users.js:42)
- Pattern: request.param -> string concat -> db.query()
### Variants Found:
1. **V-001** src/api/products.js:78 (HIGH confidence)
- Same pattern, different endpoint
- Exploitable: YES
- Fix: Use parameterized query
2. **V-002** src/api/orders.js:123 (MEDIUM confidence)
- Similar pattern, additional transform
- Exploitable: NEEDS INVESTIGATION
- Fix: Use parameterized query
3. **V-003** src/legacy/search.js:45 (LOW confidence)
- Partial match, may be sanitized upstream
- Exploitable: UNLIKELY
- Fix: Verify sanitization chain
步骤 5:修复与报告
变体分析报告
## Variant Analysis Report
**Seed**: [CVE/bug ID and description]
**Date**: YYYY-MM-DD
**Scope**: [repositories/directories analyzed]
**Tools**: CodeQL, Semgrep, manual review
### Executive Summary
- Variants found: X
- Critical: X | High: X | Medium: X | Low: X
- False positives: X
- Estimated remediation effort: X hours
### Variant Details
[For each variant: location, classification, remediation]
### Pattern Evolution
[How the pattern varies across the codebase]
### Recommendations
1. Fix all CRITICAL/HIGH variants immediately
2. Add regression tests for each variant
3. Add CI/CD checks to prevent pattern recurrence
4. Consider architectural changes to eliminate the bug class
常见漏洞种子模式
注入变体
| 种子模式 | 变体发现查询 |
|---|---|
| 通过拼接进行 SQL 注入 | source -> string.concat -> db.query |
| 通过插值进行命令注入 | source -> template.literal -> exec |
| 通过 innerHTML 进行 XSS | source -> assignment -> innerHTML |
| 通过用户路径进行路径遍历 | source -> path.join -> fs.read |
身份验证变体
| 种子模式 | 变体发现查询 |
|---|---|
| 缺少身份验证检查 | route.handler without auth.middleware |
| 弱比较 | password == input (not timing-safe) |
| 令牌复用 | token.generate without uniqueness |
相关技能
static-analysis- 使用 CodeQL 和 Semgrep,并输出 SARIFsemgrep-rule-creator- 自定义漏洞检测规则differential-review- 面向安全的差异分析insecure-defaults- 硬编码凭据和失效开放检测security-architect- STRIDE 威胁建模
Agent 集成
- security-architect(主要):威胁建模和漏洞评估
- code-reviewer(次要):感知模式的代码审查
- penetration-tester(次要):变体的漏洞利用验证
铁律
- 始终先从已确认的种子漏洞入手,再编写任何模式查询
- 绝不在验证查询能够匹配已知种子漏洞之前扩大查询范围
- 始终先用至少一个已知存在漏洞的实例测试模式查询,再进行广泛扫描
- 绝不在未通过人工分诊确认可达性和可利用性之前报告变体发现
- 始终在一个代码库中确认变体后检查所有相关代码库
反模式
| 反模式 | 失败原因 | 正确做法 |
|---|---|---|
| 仅使用精确匹配查询 | 会漏掉经过重构和语法不同的变体 | 抽象模式,并测试所有四个抽象级别 |
| 没有种子验证步骤 | 查询可能无法匹配已知漏洞 | 先用种子实例测试查询 |
| 模式范围过宽 | 误报率高,浪费分诊时间 | 使用 pattern-not 排除已知安全模式 |
| 仅扫描单个代码库 | 变体可能存在于同级代码库中 | 使用相同框架扫描所有相关代码库 |
| 找到第一个变体后就停止 | 导致该类漏洞未得到完整修复 | 在整个代码库中进行穷尽式搜索 |
记忆协议(强制)
开始之前:
阅读 .claude/context/memory/learnings.md
完成之后:
- 新模式 ->
.claude/context/memory/learnings.md - 发现问题 ->
.claude/context/memory/issues.md - 作出决策 ->
.claude/context/memory/decisions.md
假设工作可能中断:如果内容未记录在记忆中,就等于没有发生。
评论
支持 Markdown