hunt-business-logic について
セキュリティ研究者向けのビジネスロジック脆弱性調査スキルです。決済、本人確認、レート制限、アクセス制御のテストを案内し、クライアント入力への過信や検証回避、内部ページ露出などの実害につながる問題を扱います。
主な機能
- 01業務フローと信頼境界の整理
- 02決済パラメーターとコールバックのテスト
- 03本人確認・検証回避の確認
- 04レート制限と偽装可能なヘッダーのテスト
- 05内部ページと不正アクセスの調査
- 06エンドツーエンドの影響検証
活用シーン
- 01チェックアウトで価格改ざんをテスト
- 02検証がフロントエンドだけで行われていないか確認
- 03リクエストヘッダーによるレート制限回避を評価
- 04内部ページで未許可の操作ができないか確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ elementalsouls/ claude-bughunter --skill hunt-business-logicインストール後、Claude Code で/hunt-business-logicを入力して読み込まれたか確認します。
詳細
主要な標的
金銭取引、本人確認、アクセス制御が現実世界での影響と交わるプラットフォームでは、ビジネスロジックの脆弱性が最も高額な報奨金につながります。特に価値の高い標的は次のとおりです。
- Eコマースおよび決済プラットフォーム(Valve/Steam、Shopify)— 決済フローの操作、商品の無料入手、価格の改ざん
- マーケットプレイスおよびギグエコノミーアプリ(Airbnb、Uber)— 不正行為や危険なやり取りにつながる本人確認の回避
- 段階的なアクセス権を持つ SaaS(Mozilla Monitor)— 権限がないのに、確認を回避して監視機能を利用
- 利用者の多いコンシューマーアプリ(Snapchat、Yelp)— スパム、列挙、または大規模な不正利用を可能にするレート制限の回避
報奨金の対象となる資産の種類:チェックアウトフロー、サブスクリプションのエンドポイント、コールバック/確認システム、Webhook ハンドラー、インターネットに公開された従業員向け/社内ポータル、そして認可の判断にクライアントから提供されたデータを信頼するあらゆるエンドポイントです。
攻撃対象領域を示す兆候
注意すべき URL のパターン:
/checkout、/order、/subscribe、/payment、/verify、/confirm、/callback/internal、/employee、/summit、/staff、/admin— 誤って公開されている社内ページ/api/v*/payment、/api/v*/notify、/webhook— 決済プロバイダーのコールバックX-Forwarded-For、X-Real-IP、CF-Connecting-IPヘッダーを受け付けるエンドポイント
レスポンス/ヘッダーの兆候:
- カートや注文データに関連付けられた、検証されていないセッション状態を含む
Set-Cookie - レスポンスに含まれる決済プロバイダー名:
Smart2Pay、Stripe、PayPal、Braintree - サードパーティの決済ページを経由するリダイレクトチェーン(処理中のデータを狙える可能性)
- CAPTCHA やトークンがないサブスクリプション/確認エンドポイントからの
200 OK
JS のパターン:
- フロントエンドのバンドルにハードコードされた内部 URL(
/employee/、/staff/、/internal/) - サーバーに送信する前のクライアント側での価格計算
- フロントエンドでしか確認されない検証ロジック(
if (verified) { ... }) - CSRF 対策トークンやレート制限トークンのない
fetch('/api/subscribe', { method: 'POST', body: ... })
技術スタックの兆候:
- 下書き/未公開のチャネルページを持つ Shopify ストアフロント
- セッションやアカウントと紐付けず、IP ベースのレート制限を使用するアプリ
- HMAC 署名の検証を行わない決済 Webhook
- 機能を有効にする前に所有権を確認しない、SMS/電話のコールバックフロー
ステップごとのハンティング手法
-
すべての認証境界をマッピングします。 対象をクロールします。認証済みコンテンツを提供するページ/エンドポイント(従業員ポータル、プレミアム機能、注文ページなど)を特定し、それぞれ未認証の状態でテストします。JS バンドル内にインデックスされた内部ページや、robots.txt/sitemap.xml からリンクされているページを探します。
-
すべての検証フローを特定します。 メールアドレスの検証、電話番号/SMS の検証、支払い検証、CAPTCHA、年齢確認を列挙します。それぞれについて、検証手順を完全に省略するとどうなるかをテストします。有効なトークンを別のアカウントで再利用するとどうなるかも確認します。
-
すべてのフォームでレート制限をテストします。 すべての POST エンドポイント(購読、ログイン、OTP、検索など)に対して、短時間に 50 件以上のリクエストを送信します。Cookie の削除、
X-Forwarded-For/X-Real-IPヘッダーのローテーション、User-Agentの変更を試します。サーバーが接続元 IP ではなく、ヘッダー内の IP を使用しているか確認します。 -
支払いフローを傍受して改ざんします。 Burp Suite を使い、ブラウザー、アプリケーション、支払いプロバイダー間のすべてのリクエストを傍受します。価格、通貨、注文 ID、ステータスの各フィールドがどこで設定されているかを特定します。金額を $0.01 に変更したり、通貨を価値の低い通貨に変更したりしてみます。支払い確認を受け付ける POST バック/Webhook エンドポイントを探し、HMAC/署名を検証しているかテストします。
-
電話番号/コールバック番号の検証をテストします。 プラットフォームがコールバック番号を受け付ける場合は常に、自分が所有していない番号を設定できるか、その番号に電話やテキストメッセージを送信しただけで、プラットフォームが信頼済みとして扱うかをテストします。被害者の番号を設定してみます。
-
保護されていない従業員向け/内部向けの画面を確認します。 Shodan、GitHub、JS バンドル、Wayback Machine で、内部サブドメイン/パスへの参照を検索します。認証なしでアクセスできるかテストします。これらの画面から注文、データへのアクセス、権限昇格が可能か確認します。
-
ビジネス上の影響を検証します。 発見した問題ごとに、金銭的損失、不正アクセス、データ漏えいにつながるかを判断します。エンドツーエンドの攻撃チェーンを記録します。
ペイロードと検出パターン
ヘッダーのローテーションによるレート制限の回避:
# Rotate X-Forwarded-For to bypass IP rate limiting
for i in $(seq 1 100); do
curl -s -X POST https://target.com/api/subscribe \
-H "X-Forwarded-For: 10.0.0.$i" \
-H "X-Real-IP: 10.0.0.$i" \
-H "Content-Type: application/json" \
-d '{"email":"victim+'"$i"'@example.com"}' \
-o /dev/null -w "%{http_code}\n"
done
支払いの改ざん — 処理中の価格を変更:
POST /payment/initiate HTTP/1.1
Host: target.com
amount=0.01¤cy=USD&order_id=12345&product_id=99
# Look for unvalidated webhook endpoints
curl -X POST https://target.com/payment/callback \
-H "Content-Type: application/json" \
-d '{"status":"success","amount":"0.01","order_id":"12345","transaction_id":"fake-txn"}'
認証不要の内部ページの発見:
# Check robots.txt and sitemap for internal paths
curl -s https://target.com/robots.txt | grep -iE "(disallow|allow)"
curl -s https://target.com/sitemap.xml | grep -iE "(employee|internal|staff|summit|admin)"
# Grep JS bundles for internal paths
curl -s https://target.com/assets/app.js | grep -oE '"/[a-zA-Z0-9/_-]{3,50}"' | sort -u
メールアドレス検証の回避:
# Skip the verification step: hit the post-verification API endpoint directly
# with an unverified session. If it succeeds, the gate is UI-only.
curl -s -X POST https://monitor.target.com/api/monitoring/enable \
-H "Cookie: session=<your_unverified_session>" \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]"}'
# Replay verification token on different account
curl -X POST https://target.com/verify \
-d 'token=VALID_TOKEN_FROM_ACCOUNT_A&[email protected]'
クライアント側のロジックの問題を探す grep パターン:
# Find price calculations in JS
grep -iE "(price|amount|total|cost)\s*[=*+]" app.js
# Find internal URLs in JS bundles
grep -oE '"/(employee|internal|staff|admin|summit)[^"]*"' *.js
# Find unvalidated IP header usage in server code
grep -iE "x-forwarded-for|x-real-ip|cf-connecting-ip" src/ -r
よくある根本原因
-
サーバーが金銭に関わる判断に、クライアントから送信されたデータを信頼しています。 開発者が価格計算をフロントエンドに委ねたり、金額フィールドをフォーム/URL 経由で渡したりして、サーバー上で正規の情報源(商品データベース)と照合し直していません。
-
検証が UI でのみ強制され、API では強制されていません。 フロントエンドでは検証ゲートによって機能を隠していますが、バックエンド API エンドポイントは検証済みステータスがなくても完全に機能し、認証済みのリクエストなら何でも成功します。
-
IP ベースのレート制限が、偽装可能なヘッダーを参照しています。 開発者が実際の接続元 IP ではなく、
request.headers['X-Forwarded-For']を使ってレート制限を実装しているため、ヘッダーを操作するだけで簡単に回避できます。 -
支払い Webhook に署名検証がありません。 開発者が支払いプロバイダーから提供される HMAC 署名を検証せずに「成功」Webhook を実装しているため、誰でも偽の成功通知を POST できます。
-
内部向け/従業員向けページにアクセス制御がありません。 内部ツールが認証ミドルウェアなしで本番ドメインにデプロイされています。開発者が URL を公開していないことによる秘匿性に依存しているか、新しいルートへの認証適用を忘れているためです。
-
電話番号/コールバック番号の検証が推奨にとどまり、強制されていません。 システムが電話番号を受け付け、その番号を送信した人を信頼済みとして扱いますが、送信者がその番号を所有または管理していることを確認していません。
-
下書き/チャネル固有のストアフロントが、注文機能をすべて引き継いでいます。 Shopify のようなプラットフォームでは、特定のチャネル(従業員向けイベントなど)用のストアフロントを作成できます。こうしたストアフロントは非公開でも、URL が分かれば注文機能を完全に利用できます。
バイパス手法
| 防御策 | バイパス方法 |
|---|---|
| IP ベースのレート制限 | リクエストごとに X-Forwarded-For、X-Real-IP、True-Client-IP、CF-Connecting-IP ヘッダーをローテーションする |
| サブスクリプションフォームの CAPTCHA | まずヘッダーベースのバイパスを試します。CAPTCHA がウェブフォームにしかない場合は、基盤となる API エンドポイントを直接呼び出します |
| メール認証ゲート | 認証後の API エンドポイントに直接アクセスします。有効なトークンを再送します。verified=true がクライアント側で設定できる Cookie/パラメーターかどうかを確認します |
| 支払い金額のサーバー側検証 | 通貨を価値の低い通貨に変更します。$0.00 または負の金額を試します。注文 ID を操作して別の商品を参照させます |
| Webhook の HMAC 検証 | 署名ヘッダーなし/空で試します(検証がそもそも強制されているか確認します。改変したペイロードが「通る」のは、検証されていない場合に限ります)。変更していないキャプチャ済みの Webhook を再送し、冪等性/リプレイ防止が欠落していないかテストします |
| 内部ページの認証 | 未認証で試します。権限の低いアカウントで試します。パストラバーサルのバリエーションを試します(/employee/../employee/) |
| 電話番号認証(OTP 送信) | OTP 検証なしで他人の電話番号を送信します。システムが OTP 確認時ではなく、番号の送信時点で信頼を付与するか確認します |
ゲート 0 の検証
レポートを書く前に、以下の 3 つすべてに回答してください。
-
攻撃者は現時点で何を実行できますか? 具体的に説明してください。「未認証ユーザーが、物理商品を $0 で注文できます」や「攻撃者がメール認証をバイパスし、所有者でなくても任意のメールアドレスを監視できます」、または「攻撃者が任意のアドレスにサブスクリプションメールを無制限に送信できます」のように記述します。影響が曖昧な場合は却下してください。
-
被害者は何を失いますか? 具体的で、原因を特定できる損失を挙げてください。金銭的損失(無料の商品、不正な支払い)、プライバシーの損失(電話番号のなりすまし、無断の監視)、サービスの悪用(レート制限のバイパスによるスパムキャンペーン)、またはセキュリティの低下(未認証の ID が機密性の高い操作で信頼される)などです。損失が純粋に理論上のものにすぎない場合は、深刻度を再評価してください。
-
ゼロから 10 分以内に再現できますか? 新しいアカウントを作成する(またはアカウントを使わない)手順を実行します。記載した手順に従い、影響を再現してください。記載した手順で 10 分以内にエンドツーエンドの再現を確実に行えない場合、方法論が不完全です。提出前に改善してください。
実際の影響例
シナリオ 1 — 公開された社内ストアフロント経由での無料商品の取得(Shopify 形式) 従業員向けサミットのページが、スタッフに無料の書籍を配布するための非公開チャネルとして、一般公開の Shopify ストアフロントにデプロイされていました。URL は、JS バンドルの解析やリンクの共有によって発見できる状態でした。URL にアクセスした匿名ユーザーは、認証なしで商品を閲覧してチェックアウトを完了でき、会社負担で発送される物理的な商品を受け取ることができました。影響:注文ごとの直接的な金銭的損失が発生し、迅速に検知できなければ大量注文につながる可能性があります。
シナリオ 2 — 送信中の改ざんによる決済操作(Valve/Steam 形式) 決済フローでは、注文金額と通貨がクライアント側で制御可能なパラメーターを通じて渡され、その後、サードパーティの決済プロバイダー(Smart2Pay)へリダイレクトされていました。Burp Suite でリダイレクトを傍受して金額フィールドを変更すると、攻撃者は 0.01 ドルで実際の決済を完了できました。一方、HMAC 検証を行っていないアプリケーションの webhook はプロバイダーからの確認を受け入れ、アカウントに商品やサービスの全額分の価値を付与していました。影響:重大な金銭的損失が発生します。攻撃者はほぼ無コストで商品やサービスの全価値を受け取ることができ、無限に繰り返し実行できます。
シナリオ 3 — 不正な監視を可能にするメール認証の回避(Mozilla 形式) 侵害監視サービスでは、あるアドレスの監視アラートを有効にする前に、メール認証が必要でした。認証チェックは UI フローでは強制されていましたが、基盤となる API は有効なセッションがあれば任意のアドレスに対する監視設定リクエストを受け入れ、認証ステップを完全に回避できる状態でした。攻撃者は、自分が所有していないメールアドレスの監視を設定し、被害者のアカウントに関する侵害通知データ(認証情報の漏えい状況を含む可能性があります)を受け取ることができました。影響:プライバシーが侵害され、攻撃者は対象者に知られることも同意を得ることもなく、そのメールアドレスが侵害に含まれていたかどうかを把握できます。
開示済みレポートの引用(バックフィル +5 — 2016-2023)
以下の実在する、検証済みのバグバウンティ/協調的な脆弱性開示事例を、このスキルに追加します。5件すべてに、測定可能な金銭的影響(実際の損失が実証された、またはプラットフォーム全体で定量化可能なリスク)があります。
-
Stripe — 手数料割引の競合による複数回引き換え(H1 #1849626)
- サブクラス:クーポン/割引の競合による複数回引き換え+金銭的な脆弱性の要因
- ペイロード:Stripe サポートが一度限りの 20,000 ドルの手数料クレジットを適用しました。研究者は「accept-discount」POST を取得し、Burp Turbo Intruder を使って並列に 30 回再送信しました。受け入れのたびに、アカウントにクレジットが新たに付与されました
- 根本原因:割引受け入れエンドポイントに冪等性がなく、(account_id, discount_id) に一意制約がありませんでした
- 年:2023 — 5,000 ドル。修正前に手数料無料の取引が 600,000 ドル分発生(手数料率 3% で Stripe に実損約 18,000 ドル)
-
Reverb.com — ギフトカードの競合による複数回引き換え(H1 #759247)
- サブクラス:ギフトカード/ストアクレジットの競合による複数回引き換え
- ペイロード:有効なギフトカード 1 枚を使い、Turbo Intruder 経由で 10 個のソケットから
/redeemに並列 POST します。残高が額面の N 倍分付与されます - 根本原因:gift_card テーブルに行レベルのロックがなく、残高の引き落としと付与が別々のトランザクションで行われます
- 年:2019 — 1,500 ドル
-
Upserve / OLO — 数量を負にして価格を操作(H1 #364843)
- サブクラス:カート内の数量を負にして価格を改ざん
- ペイロード:
POST /api/order {"items":[{"id":1,"qty":1,"price":50},{"id":2,"qty":-3,"price":50}]}— 注文合計は-$100と計算され、決済時には約 0 ドルに切り下げられますが、料理はそのまま提供されます - 根本原因:サーバーが
qty >= 1のチェックなしにqty * priceを計算します - 年:2018 — このサブクラスの典型的な引用事例(謝辞のみのプログラム)
-
Krisp — PUT の改ざんで座席ごとの料金を減額(H1 #1446090)
- サブクラス:単価のマスアサインメント/数量割引の操作
- ペイロード:
PUT /v2/seatsのボディに、サーバーが信頼するpriceフィールドが含まれています。60 ドルの代わりにprice=1を設定します。サブスクリプションが更新され、課金エンジンは 100 席分を 1 ドル/席で請求します - 根本原因:サーバーは plan_id で価格を検索せず、リクエストボディから価格を読み取ります。典型的なマスアサインメントです
- 年:2021 — Stripe で課金される SaaS の価格設定に関するリスク
-
Stripe — フロー途中の切り替えでアーカイブ済み価格を使って決済(H1 #1328278)
- サブクラス:カート状態の TOCTOU/キャンセル後に提供(チェックアウト時の価格バージョン競合)
- ペイロード:販売者が古い価格(例:新価格 50 ドルに対して 5 ドル)をアーカイブします。購入者は新しい支払いリンクからチェックアウトを開始し、フローの途中で
price_idをアーカイブ済みのものに切り替えます。Stripe は 5 ドルを請求しますが、サブスクリプションは新しいプランで作成されます - 根本原因:支払いリンクは「有効か」を検証し、価格オブジェクトは「存在するか」を検証しますが、「price.active AND price ∈ link.allowed_prices」の結合チェックがありません
- 年:2021 — Stripe の中程度の深刻度(サブスクリプションごとに継続的な損失)
関連するスキルとチェーン
hunt-race-condition— ロジックフローにある一意性/クォータのチェックは、すべて競合状態の候補です。チェーンの基本形:ビジネスロジック(クーポン/クレジット/プロモーション)+競合状態 → Turbo Intruder で単一の TCP パケットを使い、クーポンを N 回引き換える。hunt-idor— クライアント提供の識別子(order_id、tenant_id、beneficiary_id)を信頼するロジックフローは、IDOR と直接関係します。チェーンの基本形:ビジネスロジックの手順スキップ+beneficiary_id の IDOR → 被害者の口座から資金を送金する。hunt-api-misconfig— 手順スキップや検証バイパスは、多くの場合、マスアサインメント可能なフィールドの近くにあります。チェーンの基本形:ビジネスロジックでのメール確認スキップ+API のマスアサインメント(verified:true, role:admin)→ メールアドレスを制御せずに ATO を実現する。hunt-ato— パスワードリセット、メールアドレス変更、アカウント復旧フローのロジックバグは、ATO の主要な経路です。チェーンの基本形:ビジネスロジック(再認証なしでメールアドレスの変更を受け付ける)+hunt-atoPath 2 → 被害者に気づかれずにメールアドレスを差し替える → 攻撃者のメールボックスにパスワードリセットを送信する。security-arsenal— ビジネスロジックのプローブチェックリスト(負の数量、小数のオーバーフロー、通貨の切り替え、直接 URL への移動による手順スキップ、ステートマシンの逆順操作)と、常に却下される項目のリストを読み込み、自分で引き起こした不具合を報告しないようにします。triage-validation— 7 つの質問によるゲート(特に Q4「非現実的な前提条件なしに、外部の攻撃者が悪用できますか?」)を適用します。ロジックバグには、具体的な金銭/PII/状態への影響が必要です。「フローがおかしく見える」だけでは不十分です。