draft-security-advisory について
draft-security-advisoryは、脆弱性レポートをGitHub Security Advisoryの下書きにまとめるスキルです。コード上の個別情報ではなく脆弱性のクラスを中心に、必須の文章欄とフォーム項目を整理します。
主な機能
- 01必須のアドバイザリー文章4項目の作成
- 02個別詳細を避けた脆弱性クラスの記述
- 03脆弱性に合うタイトル形式の選択
- 04レポートに基づくCVSS指標と深刻度の算出
- 05CWEとクレジットの特定
活用シーン
- 01脆弱性レポートからアドバイザリーを作成
- 02公開文から修正対象のコード経路を伏せる
- 03深刻度、影響製品、クレジットを整理
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ frappe/ skills --skill draft-security-advisoryインストール後、Claude Code で/draft-security-advisoryを入力して読み込まれたか確認します。
詳細
GitHub Security Advisory の作成者
ユーザーが提供する脆弱性レポートを、公開可能な状態の GitHub Security Advisory(GHSA)に変換します。フォームの各テキスト欄は簡潔にし、正確さは GitHub の構造化フィールドで担保します。
クラスであり、インスタンスではない
アドバイザリでは、脆弱性のクラスのレベルで説明します。脆弱性のクラス(SQL インジェクション、SSTI、認可の欠如)、破損または欠落している制御、機能領域、リスクカテゴリーが該当します。インスタンスのレベルにあるもの、つまり関数名、ファイルパス、フィールド名、エンドポイント、設定キー、コードスニペット、ペイロードはすべて記載しません。これにより、読者がアドバイザリから修正されたコードパスを逆算できないようにします。公開するアドバイザリで示す脆弱性の位置は、「特定のエンドポイント」「ある設定フィールド」「あるページ」「いくつかのレコード名」程度にとどめます。この表現の粒度に合わせてください。
タイトル
適切な既定のパターンを選んでください。同じプロジェクトの過去のアドバイザリで同じクラスを扱っている場合は、そのタイトルを一字一句そのまま再利用してください。タイトルの繰り返しはプロジェクトの慣例であり、問題ではありません。
- インジェクションの脆弱性:
{class} due to missing validation の可能性 - 認可の脆弱性:
Unauthorised {action} due to missing validation(英国式のスペル) - 結果を先に示す形式:
{Outcome} via {class}— 例:Reflected XSS によるアカウント乗っ取り - 機能を限定する形式:
{Class} in {feature area}— 他のパターンがどれも当てはまらない場合に限る最終手段です。タイトルを一意にするために使ってはいけません。アドバイザリ間で同じタイトルを使っても問題ありません。具体的な機能が明らかにならないよう、機能領域は一般化してください。脆弱性がある場所より一段広い領域を示す包括的な表現を使います(例:特定のポータルではなく「ポータルページ」)。モジュール、画面、レコードの種類は挙げないでください。
テキスト欄
GitHub のフォームには、必須のテキスト欄が4つあり、次の順に並びます。すべて公開されるため、Details と Proof of concept を含む4つすべてに、クラスとインスタンスを区別するルールを適用してください。プレースホルダーテキストが何を求めていても同様です。
各欄の役割を分け、同じ内容を繰り返さないようにしてください。
| フィールド | 内容 |
|---|---|
| Summary | 1行で記載します。脆弱性のクラスと、それが存在する包括的な領域(「ポータルページ」「特定のエンドポイント」など)を示します。 |
| Details | 1〜2文で記載します。欠落または破損していた制御と、修正内容を一般的な表現で示します(「検証を追加しました」など)。前提条件と影響を受けるリリースは記載しません。これらは Impact と Affected products にすでに記載されています。最後に回避策の文を記載します。「回避策はありません。アップグレードが必要です。」実際に回避策がある場合に限り、この文を変更してください。 |
| Proof of concept | 攻撃の概要を一般的な表現で記載します。例:「低い権限のロールを持つ認証済みユーザーが、影響を受けるエンドポイントに細工したリクエストを送信します。」ペイロード、エンドポイント名、フィールド名は記載しません。 |
| Impact | 攻撃者が得るもの、影響を受けるユーザー、必要な最小権限を記載します。 |
脆弱性のクラスに定型文がある場合は、それを再利用し、Summary と Impact に分けて記載します。
- SQL インジェクション:「特定のエンドポイントは、細工されたリクエストを通じて SQL インジェクションの脆弱性があり、悪意のある攻撃者が機密情報を抽出できる可能性がありました。」
- 認可の欠如:「特定のエンドポイントで適切な認可チェックが行われておらず、ユーザーが許可されたロールの範囲を超えてデータを変更できる状態でした。」
その他のクラスでは、同じ表現の粒度で記載します。「{曖昧な攻撃経路}を介した{クラス}により、{認証済みユーザー/悪意のあるユーザー}が{可能になること}を実行できます。」
構造化フィールド
テキストフィールドの後に、フォームの残りの値を記載します。
- CVE 識別子:「Request CVE ID later」のままにします。ドラフトの作成後に GitHub が割り当てます
- **影響を受ける製品:**現在サポートされているリリース系列ごとに 1 行記載します。レポートに記載がない場合は、どの系列がサポートされているかをユーザーに確認します。各行には、エコシステム、パッケージ名、影響を受けるバージョン
< {first fixed release}、修正済みバージョン{first fixed release}を記載します - **深刻度:**以下のルールに基づいて算出した CVSS v3.1 のベクターとスコアに加え、明白でない各メトリクスの選択(PR、S、C、I)について 1 文で根拠を記載します。その後、スコアに該当する深刻度をフォームのドロップダウンに表示される名称で記載します
- **CWE:**利用可能な中で最も具体的な ID
- **クレジット:**レポートの報告者を reporter として、修正を作成した人を remediation developer として記載します
アドバイザリはこれで完結です。根本原因の説明、ペイロード、段階的な再現手順は含めません。レポートの PoC は、概念実証フィールドに記載する攻撃の概要と CVSS メトリクスの判断にのみ使用し、それ以上には使用しません。
算出ルール
CVSS メトリクス(レポートに基づく):
- AV — Web UI 経由で到達可能な場合は Network、シェルへのアクセスが必要な場合は Local。
- AC — レポートに競合状態、非デフォルトのセットアップ、または満たすことが困難な前提条件が記載されていない限り、Low。
- PR — 認証不要の場合は None、認証済みユーザーまたは一般的な運用ロールの場合は Low、管理者またはスーパーユーザーのみの場合は High。
- UI — 被害者の操作が必要な場合を除き、None。
- S — 悪用によって、攻撃者自身の認可範囲外のリソース(テナントをまたぐデータ、またはそのロールでは通常アクセスできない種類のドキュメント)に到達する場合は Changed。
- C — 機密性の高い任意のレコードを読み取れる場合は High、範囲が限定される場合は Medium、それ以外は None。
- I — 任意の書き込みまたは削除が可能な場合は High、制約された書き込みまたは付随的な書き込みの場合は Low、読み取り専用の場合は None。
- A — サービスの中断が可能な場合は High、それ以外は None。
CWE — 利用可能な中で最も具体的なもの:
- テンプレートインジェクション → CWE-1336
- SQL インジェクション → CWE-89
- 認可の欠如 → CWE-862
- 不適切な入力検証 → CWE-20
- コードインジェクション(一般) → CWE-94
- パストラバーサル → CWE-22
- XSS → CWE-79
- SSRF → CWE-918
- XXE → CWE-611
CVSS 基本スコアに基づく深刻度の範囲:9.0–10.0 Critical · 7.0–8.9 High · 4.0–6.9 Moderate · 0.1–3.9 Low。
レポートに CVSS または CWE が記載されている場合は、その内容を検証します。分析結果と異なる場合は、分析結果を採用し、相違点を 1 文で記載します。
最終確認
タイトルと 4 つすべてのテキストフィールドを読み直します。個別のインスタンスを特定できる情報が含まれていないことを確認してください。