oss-security-audit

OSSリポジトリやプログラムに対して、認証・認可・入力検証・インジェクション・パストラバーサル・ HTTP/APIセキュリティ・レート制限・並行処理/競合状態・リプレイ・エラーハンドリング・シークレット漏洩・ 暗号・シリアライズ・依存関係障害・リソース枯渇・状態機械の不変条件・Fuzzテスト・静的解析(SAST/ 依存関係脆弱性/シークレットスキャン)・GitHub Actions/CIセキュリテ

SKILL.md

GitHub

OSSリポジトリ セキュリティ&性能監査

対象コードベースを「攻撃者視点+パフォーマンスエンジニア視点」で網羅的に検証し、 再現可能な証跡付きの所見をまとめた監査レポートを作成する。分量が多いカテゴリを1つの 巨大な調査として進めると文脈が肥大化し失敗しやすいため、カテゴリ単位のサブエージェント 呼び出しに分割し、逐次実行して構造化JSONだけを親に持ち帰る設計にしている。

実行前に必ず読むもの

  1. references/safety-and-scope.md — 何を対象にしてよいか、破壊的テストの上限。 この境界を無視した実行は絶対にしない。 対象が本番/外部/許可不明のホストなら、 実行系テストに進む前にユーザーに確認する。
  2. references/test-categories.md — 各カテゴリの実施内容の詳細(このSKILL.mdは概要のみ)

全体の流れ

Phase 0: スコープ確認(対象・所有権・破壊的テストの可否)
Phase 1: スタック検出(言語・テストフレームワーク・CI・起動方法)
Phase 2: 既存テストスイート実行(unit/integration/regression/build)
Phase 3: カテゴリ別監査を逐次サブエージェントで実施 → 各カテゴリJSONを保存
Phase 4: 静的解析・依存関係スキャン・シークレットスキャン・CI/CDセキュリティ
Phase 5: JSONを集約してレポート生成(Markdown、必要なら追加でHTML Artifact)
Phase 6: ユーザーへ納品・重大所見のサマリ報告

作業用ディレクトリを1つ切る(例: <target>/.audit-work/ または対象外の scratchpad配下)。各フェーズの出力(stack検出結果、カテゴリJSON、集約レポート)は すべてここに置く。

Phase 0: スコープ確認

references/safety-and-scope.md の「実行前チェックリスト」を実際に確認する。

  • 対象パス/URLをユーザーの指示から確認し、ローカル/自己管理下であることを確認する
  • 曖昧なら一度だけユーザーに質問する(Auto Mode下でも、破壊的テストの許可判断は ユーザーに委ねるべき境界に該当する)
  • 確認が取れたら、対象・スコープ・実施しないことをレポート冒頭に書けるようメモしておく

Phase 1: スタック検出

bash scripts/detect_stack.sh <target-dir> > .audit-work/stack.txt

出力を読み、references/stack-detection.md の対応表で以降のコマンドを決める。 検出できない場合は手動でマニフェストファイルを探す。HTTP/API系テストに必要な ローカル起動方法もこの段階で確認する(references/stack-detection.md 参照)。

Phase 2: 既存テストスイート実行

検出したコマンドで unit / integration / regression / build(型チェック・コンパイル)を実行する。 結果(pass/fail件数、失敗内容)を .audit-work/existing-tests.md にメモする。 これは「監査対象が検証済みの状態かどうか」を示す前提情報であり、レポートの Appendix に載せる。

Phase 3: カテゴリ別監査(逐次サブエージェント)

references/test-categories.md に列挙された20カテゴリ(0〜20、15bを含む)を、 サブエージェント(general-purpose、逐次起動) で実施する。このリポジトリの運用ルール上、 複数カテゴリを同時並列でサブエージェント起動すると Prompt is too long になりやすいため、 必ず1つ完了してから次を起動する(並列にはしない)。

1カテゴリ=1呼び出しに固執する必要はない。実際に運用したところ、関連の深いカテゴリを 5〜8バッチ程度にまとめて逐次実行する方が、20回別々に起動するより速く、かつ抜け漏れも 少なかった。まとめ方の目安(対象規模に応じて調整してよい):

  • 認証+認可(0,1,2)
  • 入力検証+インジェクション+パストラバーサル(3,4,5)
  • HTTP/APIセキュリティ+エラーハンドリング+シークレット(6,10,11)
  • レート制限+並行処理+リプレイ(7,8,9)
  • 暗号+シリアライズ+依存関係障害+状態機械の不変条件(12,13,14,16)
  • リソース枯渇+パフォーマンス(15,15b)
  • 回帰テスト運用+Fuzz(17,18)
  • 静的解析+GitHub/CI(19,20 — Phase 4で扱ってもよい)

カテゴリ数が多く時間がかかる場合は、ユーザーに優先順位(例: まず認証/認可/インジェクション/ シークレットの4つを先にやる)を確認してから進めてよい。単一の小さなターゲットでも、 全カテゴリを逐次で回すと1時間近くかかることがある — 見積もりを事前にユーザーに伝えておく。

各サブエージェント呼び出しのプロンプトは自己完結させる(親の会話を参照させない)。 最低限含めるもの:

  • 対象のパス/起動方法、references/safety-and-scope.md の該当する安全境界の要約
  • そのカテゴリの references/test-categories.md の該当セクションの内容(丸ごと転記してよい)
  • 必要なら references/injection-payloads.md の該当ペイロード
  • 出力形式: references/report-template.md の finding JSONスキーマ のみを最後に返すこと。 実行したコマンドの生ログを大量に返さず、要約と証跡(該当行だけの抜粋)に絞ること
  • 保存先: .audit-work/findings/<category>.json に書き込ませる(サブエージェントに 直接書かせれば親のコンテキストにJSONを流し込む必要すらない)

サブエージェント起動例(プロンプトの骨子):

あなたはセキュリティ監査の一部を担当するサブエージェントです。
対象: <path>(<起動済み|起動方法メモ>)
安全境界: <safety-and-scope.mdの要約を貼る>
担当カテゴリ: <test-categories.mdの該当セクションを貼る>
出力: 作業が終わったら .audit-work/findings/<category>.json に
  {"category": "...", "status": "...", "notes": "...", "findings": [...]}
  の形式で書き込んでください(report-template.mdのスキーマ通り)。
  最終応答には件数のサマリだけを短く書いてください。

Phase 4: 静的解析・依存関係・シークレット・CI/CD

これらは対象への負荷が小さく、1つのサブエージェント(または親スレッド)でまとめて実施してよい:

  • 依存関係脆弱性スキャン・SAST(references/stack-detection.md の対応表)
  • シークレットスキャン: bash scripts/leak_scan.sh <target-dir>
  • references/test-categories.md の 19節・20節(静的解析、GitHub/CI) 結果は同じく .audit-work/findings/static-analysis.json と .audit-work/findings/ci-cd.json に report-template.mdのスキーマで保存する。

Phase 5: レポート集約

集約スクリプトを実行する前に、.audit-work/findings/*.json を一通り見て、 異なるカテゴリのバッチが同じ根本原因を別々の所見として報告していないかを確認する (例: 「レート制限がない」がauthカテゴリとrate-limitカテゴリの両方から出る、 「TOCTOUな残高更新」がconcurrencyとreplayの両方から出る、等)。見つかった場合は、 該当するJSONファイルを直接編集して1つの所見に統合するか、片方に "duplicate_of": "<残す方のid>" を追記してから集約する。これをしないと、対象が小さい わりに所見数が水増しされ、読み手が重大度を見誤る。

python3 scripts/aggregate_report.py \
  --findings-dir .audit-work/findings \
  --target "<対象名>" \
  --commit "$(git -C <target-dir> rev-parse --short HEAD 2>/dev/null)" \
  --out <target-dir>/AUDIT_REPORT.md

生成された AUDIT_REPORT.md を読み、内容が破綻していないか(severityの偏り、 再現手順が本当に再現可能か、伏字にすべきシークレットの値がそのまま載っていないか)を 確認する。発見したシークレットの実際の値をレポートに平文で載せない — 所在(ファイル:行)とマスクした一部(例: AKIA****************)に留める。

HTML版も求められている場合(またはユーザーが見やすさを求めている場合)は、 artifact-design スキルの指示に従い、同じ内容をArtifactとして公開する (severityごとの色分け・簡単なフィルタ程度に留め、過剰な演出はしない)。

Phase 6: 納品

  • AUDIT_REPORT.md の場所をユーザーに伝える。SendUserFile で送るか、 内容が短ければチャットにサマリを書く
  • Critical/High所見がある場合は、レポート全文を読ませる前に会話内で 「◯件のcritical/high所見がある、代表例は◯◯」と一言サマリを出す
  • タスク17(回帰セキュリティテスト)の運用ルールに従い、ユーザーが実装フェーズに 進む場合は、各所見の suggested_regression_test をもとに実際のテストコードを 書くところまで支援できる旨を伝える

規模のスケーリング

対象が大きい/カテゴリ数が多い場合、全カテゴリを毎回フルで回すと時間がかかりすぎることがある。 その場合はユーザーに次のいずれかを確認する:

  • 優先度の高いカテゴリ(認証・認可・インジェクション・シークレット・依存関係)だけ先に実施し、 残りは「未実施(時間の都合、次回実施を推奨)」としてレポートに明記する
  • 複数回のセッションに分けて全カテゴリを完走する

「レポートを作ったが中身が薄い」より「実施範囲を絞って明記し、深く検証する」方を優先する。