← 一覧に戻る

ベータ前セキュリティ修正(2件)

2026年3月16日 01:23 更新
MD から自動変換されたページです。内容について質問があれば右下の ? ボタンからどうぞ。

Context

ベータ版(30-50人)リリース前の総点検で2件のセキュリティ問題を検出。 コードレビュー(code-reviewer エージェント)+ context7(Vonage API docs)+ 手動レビューの3重チェック結果。 どちらも小さな修正で防御を強化できる。


修正1: Postback キャンセルに line_user_id チェック追加

ファイル: src/index.ts 642-653行目

問題: action=cancel の Postback 処理で、リマインダーの所有者チェックがない。 SELECT/UPDATE ともに id だけで絞り込んでおり、line_user_id 条件がない。

リスク: LINE署名検証済みのため実際の悪用は極めて困難だが、defense-in-depth として必須。

修正:

// SELECT: AND line_user_id = ? を追加
const reminder = await c.env.DB.prepare(
  "SELECT id, content FROM reminders WHERE id = ? AND line_user_id = ? AND status = 'pending'",
).bind(id, userId).first<{ id: number; content: string }>();

// UPDATE: AND line_user_id = ? を追加
await c.env.DB.prepare(
  "UPDATE reminders SET status = 'cancelled' WHERE id = ? AND line_user_id = ?",
).bind(reminder.id, userId).run();

テスト: src/index.test.ts に「他ユーザーのリマインダーはキャンセルできない」テストを1件追加。


修正2: /vonage-events に共有シークレットトークン認証を追加

ファイル: src/index.ts 1429-1461行目

問題: /vonage-events エンドポイントが完全に認証なし。 URL POST https://remindenwa.com/vonage-events は推測可能で、 外部から { uuid: "...", status: "completed" } を送り込めば通話ステータスを偽装できる。

調査結果: context7 で Vonage Voice API docs を確認。Vonage は webhook コールバックに署名ヘッダーを付与しない(LINEの HMAC-SHA256 とは異なる)。標準的な対策は 共有シークレットトークンをクエリパラメータで渡す方式

修正:

app.post("/vonage-events", async (c) => {
  const token = c.req.query("token");
  if (!c.env.VONAGE_WEBHOOK_SECRET || token !== c.env.VONAGE_WEBHOOK_SECRET) {
    return c.text("Unauthorized", 401);
  }
  // ...既存処理
});

設定変更:

  1. worker-configuration.d.tsVONAGE_WEBHOOK_SECRET: string を追加
  2. Cloudflare Secrets に VONAGE_WEBHOOK_SECRET を設定: npx wrangler secret put VONAGE_WEBHOOK_SECRET
  3. Vonage ダッシュボードの event URL を https://remindenwa.com/vonage-events?token=YOUR_SECRET に変更

Note: caller.ts は per-call event_url を使っていない(アプリレベル設定のみ)。コード変更は不要。

テスト: src/vonage-events.test.ts に認証テストを追加(トークンなし→401、正しいトークン→200)。


YAGNI判定(修正不要)

項目 判定理由
timing-safe署名比較 todo.md記載済み。30-50人でタイミング攻撃は非現実的
jwt.ts単体テスト モック化済み。壊れればcron全体が失敗し即発覚
認証コードのハッシュ化 4桁+10分TTL+段階式クールダウン+10回BANの多層防御で十分
wrangler.tomlのLINE User ID 秘密情報ではない。リポジトリがprivateなら許容

進め方: TDD

各修正を RED → GREEN → REFACTOR の TDD サイクルで実装する。

TDD サイクル 1: Postback キャンセルの line_user_id チェック

TDD サイクル 2: /vonage-events のトークン認証

ドキュメント更新

YAGNI 判定した項目を以下に記録:

検証手順

  1. tsc --noEmit — 型チェック
  2. pnpm test — 全テスト通過(新規テスト含む)
📝 質問モード — テキストを選択してね
✓ 質問を送信しました