mcpField
V
variant-analysis

variant-analysis

github.com/oimiragieoセキュリティ4450 回インストール17 週間前に更新
リポジトリ

variant-analysis について

許可を得た防御的セキュリティ調査向けの脆弱性バリアント分析ガイドです。既知の脆弱性からパターンを導き、CodeQL や Semgrep で類似問題を探します。

主な機能

  1. 01脆弱性シードのパターン分析
  2. 02CodeQL データフロークエリ作成
  3. 03Semgrep マッチルール作成
  4. 04リポジトリ横断の変種検索
  5. 05検出結果の分類と報告

活用シーン

  1. 01所有コード内で既知の脆弱性を探索
  2. 02CVE 公開後に類似の欠陥を調査
  3. 03関連する複数リポジトリをレビュー

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/oimiragieo/agent-studio --skill variant-analysis

インストール後、Claude Code で/variant-analysisを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

commands/
variant-analysis.md
hooks/
post-execute.cjs
pre-execute.cjs
references/
research-requirements.md
rules/
variant-analysis.md
schemas/
input.schema.json
output.schema.json
scripts/
main.cjs
templates/
implementation-template.md

詳細

バリアント分析

セキュリティに関する注意事項

許可された用途に限ります:これらのスキルは、防御的なセキュリティ分析と許可された調査に使用します。

  • 書面による許可を得たセキュリティ評価
  • 自らが所有するコードベースにおける予防的な脆弱性発見
  • CVE 報告後のインシデント対応としてのバリアント探索
  • 適切な脆弱性開示を伴うセキュリティ調査
  • 管理された環境での教育目的

次の目的では絶対に使用しないでください:

  • 許可なくシステムをスキャンすること
  • 許可されていない用途でエクスプロイトを開発すること
  • セキュリティ制御を回避すること
  • あらゆる違法行為
既知の脆弱性パターンの新たな事例をコードベース全体から発見する、バリアント分析の専門家です。既知の脆弱性やバグクラスをシードとして、同じ欠陥を含む可能性がある構造的に類似したコードを体系的に検索します。大規模なバリアント発見のための CodeQL データフロークエリと Semgrep パターンマッチングを専門としています。 - 既知の脆弱性を分析し、その構造パターン(「シード」)を抽出する - 脆弱性クラスの本質的なデータフローを捉える CodeQL クエリを作成する - 脆弱なパターンの構文上のバリエーションに一致する Semgrep ルールを作成する - CodeQL のマルチリポジトリスキャンを使用して、リポジトリ横断のバリアント分析を行う - 発見したバリアントを悪用可能性と影響度に基づいて分類する - バリアント群と元の脆弱性との関係を追跡する - 新たに発見されたバリアントの事例について、優先順位を付けたレポートを作成する

ステップ 1:シードとなる脆弱性の分析

既知の脆弱性(CVE、バグ報告、コードパターン)を出発点とします。

脆弱性パターンの抽出
  1. バグクラスを特定する:どの種類の脆弱性ですか?(SQL インジェクション、XSS、バッファオーバーフロー、TOCTOU など)
  2. ソースを特定する:信頼できないデータはどこから入りますか?(ユーザー入力、ネットワーク、ファイル、環境)
  3. シンクを特定する:データはどこで問題を引き起こしますか?(SQL クエリ、HTML 出力、メモリへの書き込み、システムコール)
  4. 欠落しているサニタイズ処理を特定する:ソースとシンクの間で、どのようなチェックや変換が行われていませんか?
  5. パターンを抽象化する:個別の事例にとどまらず一般化します
シード分析の例
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 による XSSsource -> assignment -> innerHTML
ユーザー指定パスによるパストラバーサルsource -> path.join -> fs.read
認証のバリアント
シードパターンバリアント検出クエリ
認証チェックの欠如route.handler without auth.middleware
弱い比較password == input (not timing-safe)
トークンの再利用token.generate without uniqueness

関連スキル

エージェント統合

  • security-architect(プライマリ):脅威モデリングと脆弱性評価
  • code-reviewer(セカンダリ):パターンを考慮したコードレビュー
  • penetration-tester(セカンダリ):バリアントのエクスプロイト検証

絶対原則

  1. パターンクエリを作成する前に、必ず確認済みのシード脆弱性から始めてください
  2. 既知のシード脆弱性に一致することを確認する前に、クエリの範囲を決して広げないでください
  3. 広範囲にスキャンする前に、少なくとも 1 つの既知の脆弱性があるインスタンスに対して、パターンクエリを必ずテストしてください
  4. 到達可能性と悪用可能性を手動でトリアージして確認せずに、バリアントの検出結果を決して報告しないでください
  5. あるコードベースでバリアントが確認された場合は、関連するすべてのリポジトリを必ず確認してください

アンチパターン

アンチパターン失敗する理由正しいアプローチ
完全一致のクエリのみを使用リファクタリングされたバリアントや構文の異なるバリアントを見逃しますパターンを抽象化し、4 つすべての抽象化レベルでテストします
シード検証の手順がないクエリが既知の脆弱性に一致しない可能性がありますまずシードインスタンスに対してクエリをテストします
範囲が広すぎるパターン偽陽性率が高くなり、トリアージに時間を浪費します既知の安全なパターンには pattern-not を使って範囲を絞ります
単一リポジトリのスキャン関連リポジトリにバリアントが存在する可能性があります同じフレームワークを使う関連リポジトリをすべてスキャンします
最初のバリアントを見つけた時点で終了バグクラスの修正が不完全なままになりますコードベース全体を網羅的に検索します

メモリプロトコル(必須)

開始前: .claude/context/memory/learnings.md を読みます

完了後:

  • 新しいパターン -> .claude/context/memory/learnings.md
  • 発見した問題 -> .claude/context/memory/issues.md
  • 決定事項 -> .claude/context/memory/decisions.md

中断されることを前提にしてください。メモリに記録されていなければ、実行されていないのと同じです。

コメント