Skip to content
KitploitKITPLOIT
ツールエクスプロイトブログ
Log in
提出
ツールエクスプロイトブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
seclab-taskflows-fuzzing — GitHub Security Lab Taskflow Agent を活用した LLM 駆動のファジングパイプライン | Kitploit
ツール/GitHubGitHub/githubsecuritylab/seclab-taskflows-fuzzing
静的分析脆弱性スキャナー動的分析 (サンドボックス)脆弱性分析コード分析スクリプトと自動化ファジングマルウェア分析ユーティリティとフレームワーク
AIセキュリティ
GitHubgithubsecuritylab/seclab-taskflows-fuzzing

seclab-taskflows-fuzzing

GitHub Security Lab Taskflow Agent を活用した LLM 駆動のファジングパイプライン

リポジトリを見る
1224日前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

Seclab Taskflows Fuzzing

ネイティブ C/C++ プロジェクト向けの、LLM 駆動の OSS-Fuzz スタイルのファジングパイプライン。 実行には AFL++、カバレッジには clang+lcov、ハーネス作成、カバレッジフィードバックに基づく判断、トリアージ、レポート作成には LLM エージェントを使用。

  • 完全自律型: GitHub リポジトリを渡すだけで、ターゲットの特定から脆弱性レポートまでをすべて処理。
  • OSS-Fuzz スタイルの手法: フォーマットごとのミューテータ/辞書、構造を考慮したトークンスプライシング、カバレッジ駆動のハーネス改善。
  • 悪用可能性の判定と修正案を含む、機械可読なクラッシュレポートを生成。
  • リアルタイムのキャンペーン監視用のライブ HTML ダッシュボード。
  • Python (taskflows/toolboxes/configs) で記述され、AFL++ 用の C ハーネスを生成。
  • ステータス: 活発に開発中。

背景

このリポジトリには、 GitHub Security Lab Taskflow Agent 用の ファジングタスクフロー が含まれています。 いくつかの共有ビルディングブロック (fetch_source_code タスクフロー、local_file_viewer / gh_file_viewer ツールボックス、およびデフォルトの model_config) については、 seclab-taskflows コンパニオンリポジトリに依存しています — これらは Python の依存関係として自動的にインストールされます。

コントリビューションを歓迎します! ガイドラインについては CONTRIBUTING.md を参照してください。

要件

  • Python 3.11+
  • apt にアクセスできる Linux 環境 (または Codespace)
  • AFL++、clang、lcov、ctags、cscope、graphviz (不足している場合はパイプラインによって自動インストールされます)
  • Git および GitHub CLI (gh)

インストール```bash

pip install git+https://github.com/GitHubSecurityLab/seclab-taskflows-fuzzing

root@kitploit:~
これにより、`seclab-taskflow-agent` と `seclab-taskflows`(親)が推移的に取り込まれるため、
`seclab_taskflows.taskflows.audit.*`、
`seclab_taskflows.toolboxes.local_file_viewer`、
`seclab_taskflows.toolboxes.gh_file_viewer`、および
`seclab_taskflows.configs.model_config` という形式のすべてのドット参照が、
実行時に親ディストリビューションから解決されます。

---

## 目次

1. [これは何か](#what-this-is)
2. [クイックスタート](#quick-start)
3. [アーキテクチャ](#architecture)
4. [パイプライン、段階ごとに](#the-pipeline-stage-by-stage)
5. [カバレッジフィードバックループ](#the-coverage-feedback-loop)
6. [構造認識ファジング](#structure-aware-fuzzing)
7. [イテレーションとキャンペーンをまたぐ永続コーパス](#persistent-corpus-across-iterations-and-campaigns)
8. [トリアージと脆弱性レポート](#triage-and-vulnerability-reports)
9. [ライブダッシュボード](#live-dashboard)
10. [出力ファイル](#output-files)
11. [データベーススキーマ](#database-schema)
12. [MCP ツール(エージェントの語彙)](#mcp-tools-the-agents-vocabulary)
13. [調整可能なノブ(環境変数)](#tunable-knobs-environment-variables)
14. [パイプラインの拡張](#extending-the-pipeline)
15. [ベンチマークプロジェクトと結果](#benchmark-projects-and-results)
16. [制限事項と注意点](#limitations-and-gotchas)
17. [セキュリティ警告](#security-warning)
18. [開発:テスト、リンティング、コントリビューション](#development-testing-linting-contributing)
19. [用語集](#glossary)

---

## これは何か

このタスクフローは、完全に自律的なファジングパイプラインです。ネイティブ C/C++ プロジェクトの GitHub リポジトリを指定すると、次のことを行います:

1. 不足していれば AFL++ + clang/llvm/lcov + ctags/cscope/graphviz をインストールし、
2. ソースを取得し、
3. 候補となるファズターゲット(パーサー、デコーダー、バリデータなど)を特定し、
4. ビルドシステムを分析し、
5. ターゲットごとに 1 つ以上のハーネス候補を作成し、それぞれを AFL 計装された `.afl` バイナリとカバレッジ計装された `.cov` バイナリの両方としてビルドし、
6. (オプションで)60 秒間のカバレッジで候補を評価し、最良のものを保持し、
7. 時間予算を倍増させながらファズ/カバレッジ/改善ループを実行し、
8. すべてのクラッシュをトリアージし、以前に既知のクラッシュが依然として再現することを確認し、判定、悪用可能性、提案パッチ、回帰テストのスケッチを含むクラッシュごとの markdown 脆弱性レポートを作成し、
9. 次のキャンペーン用に Fuzz-Introspector スタイルのコールグラフ + 未到達 API レポートを構築し、
10. すべてをライブ HTML ダッシュボードに公開します。

このパイプラインは精神において **OSS-Fuzz スタイル**です。同じ手法の多く(フォーマット別ミューテータと辞書、構造認識トークンスプライシング、カバレッジ駆動のハーネス改善、機械可読レポート、重複排除されたスタックハッシュクラッシュ)を使用していますが、はるかに小さく自己完結しています。

---

## クイックスタート```bash
# Inside the codespace (or a host with python + git available):
./scripts/fuzzing/run_fuzzing.sh tukaani-project/xz

これがインターフェースの全体です。スクリプトは自律的に動作し、初回実行時に AFL++ をインストールし、その後タスクフローの残りを実行します。出力ファイルは ~/.local/share/seclab-taskflow-agent/seclab-taskflows/ に書き込まれます。

ダッシュボードはバックグラウンドで自動起動します。Codespace ではポート 8765 が自動転送されるため、任意のブラウザで開いて進行状況をリアルタイムで確認できます。

簡単なスモークテストには、小さなターゲットを使用してください:```bash ./scripts/fuzzing/run_fuzzing.sh DaveGamble/cJSON

root@kitploit:~
---

## アーキテクチャ

上から下へ3つのレイヤー:```
┌────────────────────────────────────────────────────────────────────┐
│  scripts/fuzzing/run_fuzzing.sh                                    │
│      shell driver; chains the taskflow stages with `set +e`        │
└────────────────────┬───────────────────────────────────────────────┘
                     │
                     ▼
┌────────────────────────────────────────────────────────────────────┐
│  src/seclab_taskflows/taskflows/fuzzing/*.yaml                     │
│      LLM agent prompts; one YAML per pipeline stage                │
└────────────────────┬───────────────────────────────────────────────┘
                     │  (calls MCP tools)
                     ▼
┌────────────────────────────────────────────────────────────────────┐
│  src/seclab_taskflows/mcp_servers/                                 │
│   ├ fuzz_context.py    persistence (SQLite via SQLAlchemy)         │
│   └ fuzz_runner.py     subprocess wrappers (AFL, clang, lcov, ...) │
│                                                                    │
│  scripts/fuzzing/dashboard.py                                      │
│   read-only HTML view of fuzz_context.db                           │
└────────────────────────────────────────────────────────────────────┘

主要な設計ルール:

  • MCPツールにグローバル状態を持たない。 すべてのツール関数は明示的な 引数を取り、永続的な状態は fuzz_context.db に存在する。
  • LLMエージェントが意思決定を担い、MCPツールが実行を担う。 エージェントは 何をファズするか、どのようなハーネスを書くか、どのギャップを次に追うかを 決定し、MCPツールは run_afl_for、compile_harness、store_crash などを 公開するだけである。
  • 安価に実現できる箇所では冪等性を確保する。 同じリポジトリに対して パイプラインを再実行すると、ターゲット/ハーネス/実行を重複させるのではなく アップサートする。これにより、永続的なコーパスとキャンペーン間の引き継ぎが 機能する。
  • ハーネスごとに2つのバイナリ。 AFLのエッジ計装は人間が読めるカバレッジ レポートには適していないため、各ハーネスは2回ビルドされる。1回は afl-clang-lto -fsanitize=address,undefined で(.afl バイナリ)、もう1回は clang -fprofile-instr-generate -fcoverage-mapping で(.cov バイナリ)。 .afl バイナリがファズし、.cov バイナリがAFLキューを再生して実際の ソース行/関数/ブランチカバレッジを生成する。

パイプライン、ステージごとの解説

#ステージTaskflow YAML
1AFL++ + ツール群のインストールscripts/fuzzing/install_afl.sh
2ソースの取得seclab_taskflows.taskflows.audit.fetch_source_code
3ファズターゲットの特定seclab_taskflows_fuzzing.taskflows.fuzzing.identify_fuzz_targets
4ビルドシステムの解析seclab_taskflows_fuzzing.taskflows.fuzzing.analyze_build_system
5a初期ハーネスの作成(要求時は×N候補)seclab_taskflows_fuzzing.taskflows.fuzzing.write_initial_harnesses
5bハーネスのビルド(AFL + カバレッジ)seclab_taskflows_fuzzing.taskflows.fuzzing.build_harnesses
5c候補の選別(HARNESS_CANDIDATES > 1 の場合)seclab_taskflows_fuzzing.taskflows.fuzzing.qualify_harnesses
6ファズ/カバレッジ/改善ループ(×Nイテレーション)seclab_taskflows_fuzzing.taskflows.fuzzing.fuzz_iteration
7クラッシュのトリアージseclab_taskflows_fuzzing.taskflows.fuzzing.triage_crashes
8既知のクラッシュが依然として再現することを確認seclab_taskflows_fuzzing.taskflows.fuzzing.confirm_fixed_crashes
9コールグラフ + 未到達APIレポートの作成seclab_taskflows_fuzzing.taskflows.fuzzing.analyze_call_graph
10クラッシュごとの脆弱性レポートの作成seclab_taskflows_fuzzing.taskflows.fuzzing.write_vuln_reports
11キャンペーンレポートの作成seclab_taskflows_fuzzing.taskflows.fuzzing.write_report

各ステージは、エージェントがエンドツーエンドで実行する自己完結型の taskflow YAMLである。ステージ間の通信は fuzz_context.db 内のSQLite データベースを介してのみ行われ、インメモリでの受け渡しは存在しない。


カバレッジフィードバックループ

これがパイプラインの核心である。時間予算はイテレーションごとに倍増する:``` 30s → 60s → 120s → 240s → 480s → 960s (≈ 32 min/target)

root@kitploit:~
イテレーションごと、ハーネスごとに、エージェントは次のことを行います。

1. このハーネスの安定したコーパスディレクトリを取得するために `get_persistent_corpus_dir(harness_id)` を呼び出します。
2. `run_afl_for(afl_binary_path, seed_dir=<persistent corpus>, output_dir=<run dir>, seconds=<budget>, dictionary=<auto.dict>)` を呼び出します。
3. LCOV トレースファイルと HTML レポートを生成するために `run_coverage(cov_binary_path, inputs_dir=<run>/default/queue, output_dir=<run>/coverage)` を呼び出します。
4. `coverage_report` 行と未カバー項目ごとの `coverage_gap` 行を永続化するために `store_coverage_from_lcov(run_id, lcov_path, html_path)` を呼び出します。
5. AFL のイテレーションキューを永続コーパスにマージし、サイズを抑えるために `cmin` を実行するために `fold_queue_into_persistent_corpus(...)` を呼び出します。
6. `get_coverage_summary` と `get_coverage_gaps` を読み取り、次のいずれかを行います:
   - 未カバーの分岐に到達するために新しいシード(`coverage_feedback` タグ付き)を追加する、
   - 追加の API を呼び出すようにハーネスソースを編集する、
   - ガードを満たすために AFL が必要とするマジック定数の辞書エントリを自動追加するために `enrich_dictionary_from_uncovered(...)` を呼び出す、または
   - ギャップをスキップする(コールドエラーパス / ベンダーコード)。
7. ダッシュボードのイテレーションタイムラインが何が変更されたかを追跡できるように `store_iteration_note(repo, iteration_number, harness_id, note=<one line summary>)` を呼び出します。

**プラトー検出。** 2 回連続のイテレーションで行カバレッジの絶対パーセンテージポイントの増加が両方とも `< FUZZ_PLATEAU_THRESHOLD_PCT`(デフォルト `1.0`)未満になると、ループは早期に終了します。

---

## 構造認識ファジング

3 つの相補的なメカニズムが、生のバイト変更よりも強力な入力を生成します。

### 1. フォーマット別辞書 + カスタムミューテータ

`input_kind` が既知のフォーマットに一致するターゲット向けに、タスクフローは事前構築済みの辞書と `LLVMFuzzerCustomMutator` C ソースファイルを提供します:

| フォーマット | 辞書 | ミューテータ | 備考 |
|--------|------------|---------|-------|
| `json` | `json.dict` | `json_mutator.c` | トークンスプライス、バランス括弧の複製/削除、型反転 |
| `xml` | `xml.dict` | `xml_mutator.c` | タグ、エンティティ、DTD、billion-laughs トークン |
| `regex` | `regex.dict` | `regex_mutator.c` | アンカー、クラス、量指定子、実際の ReDoS パターン |
| `binary_tlv` | _(none)_ | `binary_tlv_mutator.c` | 長さプレフィックス付きレコード:長さオーバーフロー / 複製 / 削除 |
| `png` | `png.dict` | _(reuses binary_tlv)_ | PNG 辞書 + binary_tlv ミューテータ |

これらは `write_initial_harnesses`(辞書がシードの隣にコピーされる)と `build_harnesses`(ミューテータが AFL バイナリにリンクされる)によって自動的に取り込まれます。各ミューテータはミューテーションの 50% を AFL のデフォルトバイトミューテータに委譲するため、エンジンのランダム化を失いません。

新しいフォーマットを追加するには:`<name>.dict` および/または `<name>_mutator.c` を `src/seclab_taskflows/dictionaries/` に配置し、`fuzz_runner.py` の下部にある `_FORMAT_ASSETS` マップに登録します。

### 2. ソース認識(プロジェクト固有)スマートミューテータ

馴染みのないフォーマットの場合、またはより強力なプロジェクト固有のトークンが必要な場合は常に、`generate_smart_mutator` がターゲットリポジトリ自身の `.c`/`.h` ファイルをスキャンし、スプライス辞書が以下から抽出された `LLVMFuzzerCustomMutator` C ファイルを出力します:

- 3 文字以上の英字を含む文字列リテラル(コンパイラ/ライセンスノイズ、パス、ヘッダー、asm 制約、フォーマット指定子をフィルタリングした後)、
- `#define`、`case`、`enum` からの 32 ビット数値定数(0、1、256、0xff… のような一般的な小整数ノイズをフィルタリングした後)。

3 つのフォーカスが利用可能です:

| フォーカス | スプライスするもの | 使用する場面 |
|-------|-----------------|-------------|
| `strings` | プロジェクトの文字列リテラルのみ | テキストフォーマット(JSON、XML、YAML、CSV) |
| `constants` | 32 ビット数値マジック値のみ | バイナリプロトコル、マジックナンバーを含むヘッダー |
| `combined` | 両方 | デフォルト;通常は最良 |

`generate_smart_mutators(...)`(複数形)を `HARNESS_CANDIDATES >= 3` と組み合わせて、各フォーカスが予選ラウンドで候補ハーネスになるようにします。

### 3. プロジェクト認識 AFL 辞書 + カバレッジ駆動型エンリッチメント

2 つの相補的なツールが、キャンペーンの進行に合わせて AFL `-x` 辞書を構築・拡張します:

- **`generate_project_dictionary(source_root, output_path)`** — イテレーション 1 の前に 1 回実行され、スマートミューテータが使用するのと同じソーストークンセットを静的に抽出し、AFL 辞書として書き出します。数値定数は両方のエンディアンで出力されるため、ファザーはホストのバイトオーダーに関係なく `memcmp(x, &magic, 4)` を満たすことができます。

- **`enrich_dictionary_from_uncovered(source_root, dictionary_path, uncovered_locations)`** — 各イテレーションのカバレッジステップの後に実行され、未カバー行の周辺のソースを条件付きガード(`strncmp/memcmp/strstr`、`case 0xN:`、`== 0xN`、`== 'X'`)についてスキャンし、新しいトークンを辞書に追加します。冪等:すでに存在するエントリを再追加することはありません。

### 4. コーパススプライス演算

`corpus_dir` が `generate_smart_mutator` に渡されると、生成された C はコーパススプライス演算子も取得します:最初の呼び出しでそのディレクトリから最大 64 ファイル(各 4 KiB に制限)をロードし、それ以降はそれらのファイルのランダムなサブリージョンをミューテーションされた入力にスプライスできます。これにより、AFL の標準 havoc がうまく行わない再結合スタイルの演算子をミューテータに与えます。`get_persistent_corpus_dir(...)` と組み合わせて、スプライスライブラリが「AFL がすでに発見したものをリミックスする」ようにします。

---

## イテレーションとキャンペーンをまたぐ永続コーパス

各ハーネスには次の場所に安定したコーパスディレクトリがあります:```
<workspace>/corpus/harness_<id>/

fuzz_iteration が run_afl_for の seed_dir として使うのはこれである(<harness>/seeds ではなく)。各イテレーションの終わりに、fold_queue_into_persistent_corpus(...) が AFL のイテレーションキューをこのディレクトリにマージし、afl-cmin を実行してサイズを抑える。

その結果、昨日のキューが今日の実行に引き継がれ、同じプロジェクトの再実行にも引き継がれる。キャンペーンを停止して再起動しても、進捗は失われない。


トリアージと脆弱性レポート

fuzz/coverage/improve ループが終了すると、3 つのステージが自動的に実行される:

1. triage_crashes

<run>/default/crashes/ 内のすべてのクラッシュファイルに対して:

  • afl-tmin で入力を最小化し、
  • replay_under_asan でスタックトレースと stack_top_hash を取得する (上位 N 個の正規化フレーム。テンプレート、libcxx のインライン名前空間、匿名 名前空間、LTO の数値サフィックスは除去されるため、意味的に 同一のクラッシュは同一のハッシュになる)、
  • ハッシュで重複排除し、バグクラス分類 + 信頼度ノート(high / medium / low)を 伴う crash 行を永続化する。

2. confirm_fixed_crashes

以前に分類されたすべてのクラッシュ(判定がまだ fixed/duplicate/non_reproducible でないもの)を、現在の AFL+ASan バイナリで 再生する。もはやクラッシュしなければ、verdict="fixed" をマークする。前回の キャンペーン以降にアップストリームの修正が適用されたプロジェクトに対して キャンペーンを再実行する際に有用である。

3. write_vuln_reports

一意のクラッシュごとに、エージェントはハーネスのソース + クラッシュした 関数のソースを読み、公開 API からの呼び出しチェーンをたどり、次に 10 種類の OSS-Fuzz スタイルの判定のいずれかを割り当て、markdown の脆弱性 レポートを書き出す:

判定意味
vulnerability実際に存在し、公開 API を通じて悪用可能
library_hardening実際のバグだが、現実的な公開 API 経路がない。ライブラリは依然として自己防御すべき
harness_bugバグはライブラリではなく、我々のハーネスにある
non_reproducible最小化された入力で再生してもクラッシュが再現しない
oomメモリ不足。攻撃者が制御できるサイズが無制限の場合にのみ脆弱性
timeoutアルゴリズム的な爆発による DoS
assertion_failureassert() に到達。セキュリティ上の関連性は様々
fixedconfirm_fixed_crashes によって設定:入力がもはや再現しない
duplicate異なるスタックハッシュを持つ別のクラッシュと同じ根本原因
needs_investigation判定できなかった。人間によるレビューのためにフラグ付け

各脆弱性レポートには以下が含まれる:

  • 判定 + バグクラス + CWE + 深刻度 + 信頼度
  • file:line 参照付きの根本原因分析
  • 公開 API からの到達可能性(具体的な呼び出しチェーン)
  • 悪用可能性の評価(読み取り vs. 書き込み、攻撃者の制御、緩和策)
  • unified diff としての修正案(「review required」とマーク)
  • リグレッションテストのスケッチ

ライブダッシュボード

ダッシュボードは run_fuzzing.sh によってバックグラウンドで自動的に 起動される。FUZZ_NO_DASHBOARD=1 で無効化できる。ポートは FUZZ_DASHBOARD_PORT で上書きできる(デフォルト 8765)。

Codespace では、ポート 8765 は自動転送される — 転送された URL を 任意のブラウザで開けばよい。ページは 5 秒ごとに自動更新され、以下を表示する:

  • 判定サマリーチップ — 判定カテゴリごとのカウント、総実行数、 パス、総実行回数、クラッシュ
  • ライブの「running」パルス インジケーター — リポジトリごと、および 実行中の fuzz_run を持つハーネスごと
  • カバレッジトレンドテーブル — インライン SVG スパークラインと イテレーションごとの差分列付き
  • コールグラフ & 未到達の API サーフェス — Fuzz-Introspector-lite スナップショット
  • クラッシュテーブル — 判定でソート(vulnerability が先頭)、 各脆弱性レポートと最小化された入力にリンク
  • クラッシュヒートマップ — (ハーネス × イテレーション) ごとの クラッシュ数グリッド、不透明度はカウントに応じてスケール
  • イテレーションタイムライン — 各イテレーションで何が変わったかを 記述したエージェント作成の一行ノートの時系列フィード
  • 未カバーの上位関数 — デフォルトで折りたたみ

JSON API

ダッシュボードはスクリプト向けに小さな読み取り専用 JSON API も 公開している:```bash

All known repos

curl http://127.0.0.1:8765/api/json

Per-repo: harnesses, per-iteration coverage, crashes with verdicts

curl 'http://127.0.0.1:8765/api/json?repo=kkos/oniguruma' | jq .

root@kitploit:~
---

## 出力ファイル

すべて `~/.local/share/seclab-taskflow-agent/seclab-taskflows/` 配下にあります。

| パス | 内容 |
|------|----------|
| `fuzz_context/fuzz_context.db` | SQLite — ターゲット、ハーネス、実行、カバレッジ、クラッシュ、判定、コールグラフ、ハーネス候補、イテレーションノート |
| `fuzz_runner/builds/` | ビルド済みの `.afl` および `.cov` バイナリ |
| `fuzz_runner/runs/` | AFL 出力ディレクトリ + LCOV ファイル + HTML カバレッジレポート |
| `fuzz_runner/corpus/harness_<id>/` | ハーネスごとの永続コーパス(イテレーションとキャンペーンをまたいで引き継がれる) |
| `fuzz_runner/repo/<owner>__<repo>/REPORT.md` | Markdown キャンペーンサマリ、判定別にグループ化されたクラッシュ |
| `fuzz_runner/repo/<owner>__<repo>/vuln_<crash_id>.md` | クラッシュごとの Markdown 脆弱性レポート |
| `fuzz_runner/repo/<owner>__<repo>/call_graph.{dot,svg,md}` | 静的コールグラフ + 到達/未到達のオーバーレイ |

---

## データベーススキーマ

`fuzz_context.db` 内のテーブル(SQLAlchemy 経由の SQLite):

| テーブル | 注目すべきカラム |
|-------|--------------------|
| `fuzz_target` | `repo, file, function, signature, input_kind` |
| `harness` | `target_id, repo, harness_path, afl_binary_path, cov_binary_path, build_status, version, sanitizers` |
| `seed_corpus` | `target_id, source, path, bytes_count, added_in_iteration` |
| `fuzz_run` | `harness_id, iteration_number, exec_per_sec, paths_total, crashes_count, status, output_dir, started_at, ended_at` |
| `coverage_report` | `run_id, lines_total, lines_hit, line_pct, fns_*, branches_*, lcov_path, html_path` |
| `coverage_gap` | `report_id, file, function, line, kind, reason_hint` |
| `crash` | `run_id, input_blob_path, minimized_path, stack_top_hash, sanitizer_output, verdict, bug_class, cwe, severity, vuln_report_path, reproducer_path, classification, notes` |
| `call_graph` | `repo, target_id, dot_path, svg_path, functions_total, functions_in_graph, functions_reached, functions_unreached, untouched_surface_json` |
| `harness_suggestion` | `repo, function_name, file, rationale, input_kind, priority` |
| `iteration_note` | `repo, harness_id, iteration_number, note, created_at` |

スキーママイグレーションは `fuzz_context.py` の `_migrate()` にあります。新しいテーブルは
`Base.metadata.create_all()` によって自動的に作成されます。PRAGMA ベースの `ALTER TABLE` が
必要なのは新しいカラムのみです。

---

## MCP ツール(エージェントの語彙)

エージェントは AFL や clang を直接呼び出すことはありません — MCP ツールを
呼び出すことでパイプラインを構成します。目的別にグループ化した全ツールセットは以下のとおりです:

### 永続化 (`fuzz_context.py`)

- `store_fuzz_target`, `get_fuzz_targets`
- `store_harness`, `update_harness_build`, `get_harnesses`
- `store_seed`, `start_fuzz_run`, `finish_fuzz_run`, `get_fuzz_runs`
- `store_coverage_from_lcov`, `get_coverage_summary`, `get_coverage_gaps`,
  `coverage_plateau_reached`
- `store_crash`, `update_crash_verdict`, `get_crashes`,
  `get_crashes_grouped`, `suggest_severity`
- `store_call_graph`, `get_call_graphs`, `get_repo_reached_functions`
- `store_harness_suggestion`, `get_harness_suggestions`
- `store_iteration_note`, `get_iteration_notes`

### ビルド / ファズ / カバレッジ (`fuzz_runner.py`)

- `check_tooling`, `workspace_paths`
- `compile_harness` — `.afl` および `.cov` バイナリをビルド
- `run_afl_for`, `cmin`, `tmin`, `replay_under_asan`, `reproduce_crash`
- `run_coverage` — `.cov` バイナリに対して AFL キューをリプレイし、LCOV をエクスポート
- `extract_dictionary` — バイナリから印刷可能な文字列を抽出
- `package_reproducer` — 単一クラッシュの `.tgz` をバンドル

### 永続コーパス (v8)

- `get_persistent_corpus_dir`, `fold_queue_into_persistent_corpus`

### フォーマットアセット (C5)

- `list_format_assets`, `get_format_dictionary`, `write_format_mutator`

### スマートミューテータ + プロジェクト対応辞書

- `generate_smart_mutator`, `generate_smart_mutators`
- `generate_project_dictionary`, `enrich_dictionary_from_uncovered`

ツール関数は `@mcp.tool()` (FastMCP) でデコレートされています。テスト内では、
`.fn` 属性を介して呼び出します。例:
`fr.run_afl_for.fn(afl_binary_path=..., ...)`。

---

## 調整可能なノブ(環境変数)

| 変数 | デフォルト | 目的 |
|----------|---------|---------|
| `HARNESS_CANDIDATES` | `1` | ターゲットごとに書き込まれる候補ハーネスの数。OSS-Fuzz-Gen スタイルの競争には 2 または 3 に設定します。予選ステージでは各候補を `QUALIFIER_SECONDS` の間実行し、行カバレッジ % で最良のものを保持します。 |
| `QUALIFIER_SECONDS` | `60` | 予選ステージにおける候補ごとの実時間予算。 |
| `FUZZ_PLATEAU_THRESHOLD_PCT` | `1.0` | 連続する 2 回のイテレーションがプラトーと見なされ、ループが早期に停止する、行カバレッジの増加量(絶対 pp)のしきい値。 |
| `FUZZ_DASHBOARD_PORT` | `8765` | ライブダッシュボードのポート。 |
| `FUZZ_NO_DASHBOARD` | (未設定) | `1` に設定するとダッシュボードの起動をスキップします。 |
| `FUZZ_RUNNER_TIMEOUT` | `1200` | `fuzz_runner` におけるツールごとのサブプロセスタイムアウト(秒)。 |
| `LOCAL_SHELL_TIMEOUT` | `180` | `local_shell` におけるコマンドごとのタイムアウト(秒)。 |

さらに標準的なエージェント変数(`COPILOT_TOKEN`, `LOG_DIR`,
`FUZZ_CONTEXT_DIR`, …)があります。完全なリストはプロジェクトルートの README を参照してください。

---

## パイプラインの拡張

### 新しいフォーマットの追加(ミューテータ + 辞書)

1. `dictionaries/<name>.dict`(AFL `-x` フォーマット)および/または
   `dictionaries/<name>_mutator.c`(libFuzzer カスタムミューテータ)を配置します。
2. `fuzz_runner.py` の末尾にある `_FORMAT_ASSETS` に登録します:   ```python
   "<name>": {
       "dictionary": "<name>.dict",
       "mutator": "<name>_mutator.c",
       "description": "Short one-liner about the format",
   },
  1. エージェントは list_format_assets() を通じて自動的にそれを取得します。

新しい MCP ツールの追加

  1. fuzz_context.py(永続化用)または fuzz_runner.py(サブプロセス作業用)に @mcp.tool() デコレートされた関数を追加します。
  2. すべての引数に Annotated[type, Field(description=...)] を使用します — この description が LLM に見えるものです。
  3. tests/test_fuzz_context.py / tests/test_fuzz_runner.py にユニットテストを追加します。ツールはその .fn 属性を介して呼び出します(FastMCP の慣例)。
  4. 関連する taskflow YAML の user_prompt で新しいツールを参照します。

新しいパイプラインステージの追加

  1. src/seclab_taskflows/taskflows/fuzzing/ に新しい YAML を作成します。既存のファイル(例: triage_crashes.yaml)をテンプレートとして使用します。
  2. scripts/fuzzing/run_fuzzing.sh の適切な既存の 2 つのステージの間に組み込みます。
  3. (任意)scripts/fuzzing/dashboard.py にステージ固有のダッシュボードセクションを追加します。

スキーママイグレーション

新しい SQL テーブルを追加する場合:

  • fuzz_context_models.py に SQLAlchemy モデルを追加します。
  • 他に必要なものはありません — Base.metadata.create_all() がエンジン初期化時に呼び出され、新しいテーブルが自動的に作成されます。

既存のテーブルに新しいカラムを追加する場合:

  • SQLAlchemy モデルを更新します。
  • fuzz_context.py の _migrate() に PRAGMA table_info + ALTER TABLE ADD COLUMN ブロックを追加し、古い DB が透過的にアップグレードされるようにします。
  • そのカラムがダッシュボードで読み取られる場合は、scripts/fuzzing/dashboard.py の _migrate_if_writable() も更新します。

ベンチマークプロジェクトと結果

benchmark/projects.yaml に参照プロジェクトが一覧されています。これらは、完全な v4+ パイプラインが人手を介さずに codespace 開発イメージ上でエンドツーエンドで実行できるように選ばれています。

#リポジトリ興味深い理由備考
1tukaani-project/xz実世界のパーサー重視のライブラリ(liblzma)。豊富なフィルタチェーン + 整数/VLI パース面ベースライン
2DaveGamble/cJSON小さな単一ファイル C JSON パーサー。簡単な CMakeパイプラインのクイックスモーク
3akheron/janssonコンパクトな C JSON ライブラリ。文書化された json_loadb() バイトバッファエントリポイントを持つCMake。非常に高速な exec/sec
4libexpat/libexpat成熟したストリーミング XML パーサー。多くの歴史的 CVECMake または autotools
5kkos/oniguruma正規表現エンジン。攻撃者パターン + 対象文字列を受け取るAutotools。パターンコンパイルがホットパス

codespace 開発イメージ上での完全な v4 パイプライン実行からの参照数値(≈32 分/ターゲット):

リポジトリターゲットハーネスAFL 実行クラッシュ判定
tukaani-project/xz88480—
DaveGamble/cJSON66360—
akheron/jansson773510harness_bug, library_hardening, duplicate, needs_investigation
libexpat/libexpat33180—
kkos/oniguruma10106013vulnerability(×2 regerror.c の OOB 読み取り), library_hardening, harness_bug, non_reproducible

xz / cJSON / libexpat のゼロクラッシュ結果は予想通りです。これらのプロジェクトは上流で集中的にファジングされています。oniguruma で vulnerability に分類された 2 件の所見は、onig_snprintf_with_pattern の警告フォーマットコードパスにおける実際の範囲外読み取りです(パターンがバックスラッシュで終わる場合に pat_end を 1 バイト超えて読み取る)。クラッシュごとの markdown レポートには推奨パッチが含まれています。

新しいベンチマークプロジェクトを追加するには、benchmark/projects.yaml にエントリを追加し、(任意で)その理由を benchmark/README.md に記述します。既存の analyze_build_system ステージが clang + AFL++ フラグでビルドできるものであれば、妥当な候補です。純粋な C のパーサー、デコーダー、シリアライザーが最もよく機能する傾向があります。


制限事項と注意点

  • C / C++ のみ。 AFL++ はネイティブインストルメンテーションファザーです。
  • ビルドシステム依存。 非自明なビルドシステム(カスタム Bazel ルール、ベンダー化された libc、独自ビルドツール)を持つプロジェクトは、clang/AFL フラグでのビルドに失敗する可能性があります。エージェントはそれらのターゲットを BUILD_FAILED: とマークしてスキップします。
  • Codespace の AFL 警告。 AFL++ は kernel.core_pattern=core と CPU ガバナーの調整を要求します。Codespace ではこれらが利用できないため、taskflow はデフォルトで AFL_SKIP_CPUFREQ=1 と AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 をエクスポートします。AFL は警告を出力しますが、libFuzzer スタイルの abort 処理によりクラッシュを発見します。
  • モデル依存。 エージェントのハーネス作成品質は、基盤モデルの対象コードへの理解によって制限されます。
  • POSIX 専用のスマートミューテーターコーパススプライス。 コーパススプライス操作は <dirent.h> を使用します。Linux/macOS では問題ありませんが、Windows ではコンパイルできません。
  • stdin モードの注意点。 compile_harness でビルドされた AFL バイナリは argv モードで libAFLDriver を使用します。そのため replay_under_asan と tmin はデフォルトで stdin_input=False になります。libAFLDriver は stdin 経由で駆動されると無限ループするためです。
  • generate_smart_mutator + generate_smart_mutators は Python の .format() を使用 — C テンプレート内のすべてのリテラル { / } は二重にする必要があります({{ / }})。テンプレートを編集して KeyError が出始めたら、これが原因です。

セキュリティ警告

この taskflow は afl-fuzz、clang、llvm-cov、および LLM が選択した任意のビルドコマンドを、ホスト上で直接(コンテナなしで)実行します。プロンプトインジェクションされたエージェントは、原理的にはあなたのユーザーができることは何でもできてしまいます。以下の場合にのみ実行してください:

  • 使い捨て環境(GitHub Codespaces、使い捨て VM など)内で、
  • 昇格された権限なしで、
  • ネットワークアクセスを git、apt、ビルドシステムが必要とする範囲に限定して。

local_shell ツールボックスは確認プロンプトの背後にありません — taskflow は自律的で人間がループに入らずに実行されるため、対話的な確認は永遠にブロックするだけです。すべてのシェルコマンドは事後レビューのために $LOG_DIR/mcp_local_shell.log に記録されます。


開発: テスト、リンティング、コントリビューション```bash

Run the test suite (Python 3.11+ required by hatch-test envs)

hatch test

Run the linter

hatch fmt --linter --check

Auto-fix lint issues

hatch fmt --linter

Lint a single file

hatch fmt --linter --check -- src/seclab_taskflows/mcp_servers/fuzz_runner.py

root@kitploit:~
コードベースの規約(これらのキャンペーン履歴版については `benchmark/improvements.md` も参照):

- `os.environ.get(NAME, "default")` ではなく `os.environ.get(NAME) or "default"` を使用すること。そうしないと、YAML テンプレート置換による空文字列が返されてしまう。
- 新しいアノテーションには `Optional[X]` ではなく `X | None`(PEP 604)を使用すること。
- テストはデコレートされた名前を直接呼び出すのではなく、`.fn(...)` を介して MCP ツールを呼び出すこと。
- テスト内で `/tmp/...` リテラルを避けること — `tmp_path` pytest フィクスチャを使用すること(lint ルール `S108`)。
- テストメソッド内のすべてのインラインインポートは、ファイルの先頭に移動できない場合(例えば `pytest.skip` の後に条件付きでインポートする場合)、`# noqa: PLC0415` が必要。
- 複合的な真偽テストは 1 行につき 1 アサーションとすること(lint ルール `PT018`)。

改善トラッカー(`benchmark/improvements.md`)は、バージョン間でパイプラインに追加された内容の永続的なログです。実質的な機能を追加した際は、何が変更されたか、どこに存在するか、どのテストがそれを保護しているかを記述したセクションをそこに追加してください。

---

## 用語集

- **AFL++** — カバレッジガイド型グレーボックスファザー。ここでの実行エンジン。
- **libAFLDriver** — AFL++ ハーネスが libFuzzer のエントリポイント規約(`LLVMFuzzerTestOneInput`)を使用できるようにする静的ライブラリ。
- **LCOV** — 業界標準のカバレッジトレースファイル形式。`llvm-cov export -format=lcov` を介してエクスポートし、独自に解析します。
- **`stack_top_hash`** — ASan/UBSan スタックトレースの正規化された上位 N フレームの 16 文字ハッシュ。クラッシュの重複排除に使用されます。
- **永続コーパス** — `<workspace>/corpus/harness_<id>/` にあるハーネスごとのディレクトリで、AFL の興味深い入力をイテレーションや同じキャンペーンの再実行をまたいで保持します。
- **スマートミューテータ** — スプライストークンがターゲット自身のソースコードから抽出される `LLVMFuzzerCustomMutator`(`generate_smart_mutator`)。
- **カスタムミューテータ(libFuzzer)** — バッファをどのようにミューテートするかを完全に自由に決定できる、ユーザー提供の C 関数。エンジンから呼び出されます。AFL++ も同じ ABI をサポートしています。
- **MCP ツール** — LLM エージェントが呼び出せる FastMCP でデコレートされた関数。
- **OSS-Fuzz / Fuzz-Introspector** — Google のオープンソースファジングインフラストラクチャと、そのコンパニオンであるコールグラフ/カバレッジ分析ツール。このタスクフローのいくつかの機能(フォーマットごとのミューテータ、スタックによる重複排除、コールグラフ + 未到達 API レポート、マルチ候補ハーネス)は、これらに触発されています。

---

## ライセンス

このプロジェクトは MIT オープンソースライセンスの条件の下でライセンスされています。完全な条件については [LICENSE](https://github.com/githubsecuritylab/seclab-taskflows-fuzzing/blob/main/LICENSE.txt) ファイルを参照してください。

## メンテナ

[CODEOWNERS](https://github.com/githubsecuritylab/seclab-taskflows-fuzzing/blob/main/CODEOWNERS) を参照するか、GitHub Security Lab チームにお問い合わせください。

## サポート

このプロジェクトに関するヘルプの入手方法の詳細については [SUPPORT.md](https://github.com/githubsecuritylab/seclab-taskflows-fuzzing/blob/main/SUPPORT.md) を参照してください。

## 謝辞

このプロジェクトは [AFL++](https://github.com/AFLplusplus/AFLplusplus)、[OSS-Fuzz](https://github.com/google/oss-fuzz)、および [Fuzz-Introspector](https://github.com/ossf/fuzz-introspector) の概念と技術の上に構築されています。
ツールをダウンロード