概要
リリース前会議(Blog #024)で特定されたP0課題2件を修正するセキュリティスプリントです。
| 課題 | 修正前 | 修正後 |
|---|---|---|
| Stripe Webhook tier判定 | ハードコード "starter" | metadata / price_id / amount で判定 |
| Webhook署名検証 | 検証なし(全POSTを受理) | HMAC-SHA256 署名検証 |
1. Stripe Tier判定ロジック修正
以前のコードでは、checkout.session.completed イベント受信時にtierが "starter" にハードコードされていました。Proプランを購入してもStarterに割り当てられるバグです。
修正アプローチ: 3段階フォールバック
// Priority順:
// 1. metadata["tier"] — checkout作成時に埋め込み
// 2. price_id マッチ — 環境変数の既知price_idと照合
// 3. amount_total — 金額ベースのフォールバック
pub fn determine_tier(session: &Value) -> &'static str
さらに、checkout session作成時に metadata[tier] を自動的に埋め込むよう create_checkout_session() も修正しました。
2. Stripe Webhook署名検証
Stripeは各webhook呼び出しに Stripe-Signature ヘッダーを付与します。このヘッダーには:
t=: UNIXタイムスタンプ(リプレイ攻撃防止)v1=: HMAC-SHA256署名(改ざん検知)
// 検証ロジック:
// 1. ヘッダーからtとv1を解析
// 2. タイムスタンプが5分以内か確認
// 3. HMAC-SHA256("${t}.${body}", webhook_secret) を計算
// 4. hex(result) == v1 なら合格
STRIPE_WEBHOOK_SECRET が未設定の場合は検証をスキップ(開発環境用)。本番では必ず設定します。
3. LINE Webhook署名検証
LINE PlatformはWebhook呼び出し時に X-Line-Signature ヘッダーを付与します。
// 検証ロジック:
// 1. HMAC-SHA256(channel_secret, body_bytes) を計算
// 2. Base64エンコード
// 3. X-Line-Signature ヘッダー値と比較
LINE_CHANNEL_SECRET 環境変数で制御。LINE webhookハンドラはJSONパース前に署名を検証するよう変更しました。
4. テスト結果
全10テストが合格。新規4テストを追加しました。
| テスト名 | 検証内容 | 結果 |
|---|---|---|
stripe_signature_verification_works | 正当/不正署名の判定 | PASS |
determine_tier_from_metadata | metadata.tierからPro判定 | PASS |
determine_tier_from_amount | amount_totalからPro判定 | PASS |
line_signature_verification_works | 正当/不正LINE署名の判定 | PASS |
| その他既存テスト (6件) | ALL PASS | |
5. 追加クレート
| クレート | バージョン | 用途 |
|---|---|---|
hmac | 0.12 | HMAC計算(Stripe/LINE共通) |
sha2 | 0.10 | SHA-256ハッシュ |
hex | 0.4 | Stripe署名のhexエンコード |
base64 | 0.22 | LINE署名のBase64エンコード |
変更ファイル
crates/api/Cargo.toml— hmac, sha2, hex, base64 追加crates/api/src/billing.rs—determine_tier(),verify_stripe_signature(),price_id_to_tier()追加crates/api/src/line.rs—verify_line_signature()追加crates/api/src/main.rs— Webhook handlers にヘッダー検証追加、テスト4件追加
P0課題2件を完了。ベータ公開に向けた最大のセキュリティリスクが解消されました。次のSprint 13ではP1課題(レート制限、入力バリデーション、GA設定、LINE紐付け)に取り組みます。