traPtitech / traPtitech/Checkin

認可・レート制限を導入し、無認証アクセスを塞ぐ

Open
#15 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
TypeScript
Stars
0
Forks
0
Avg merge
3d 5h
Merged PRs (30d)
7

Description

背景

現状、oRPC の全プロシージャは pub(implement(contract).$context<Context>(), packages/api/src/orpc.ts)で公開されており、認可チェックが一切ない。認証サブシステム(#16)自体が未実装のため、これまでは許容済みの既知リスクとして扱ってきた。しかし Stripe をラップする API の実装が進み、リスクは読み取り専用の情報露出から、**無認証での書き込み(金銭移動・業務データ改変)**へと具体化・拡大している。デプロイは本 issue 完了まで不可。

問題

  1. 無認証での全件列挙: prices / products / invoices / checkout の list を無認証で全件列挙でき、金額・customer ID・status 等が露出する。
  2. 無認証でのミューテーション: prices.update / products.update(有効・無効や名称・説明の改変)、invoices.create(任意 customer/price への請求作成・確定)が無認証で実行できる。とくに Product の name / description は Stripe ホストの請求書・Checkout ページに表示されるため、保存されたフィッシング文言が第三者に表示される注入経路になる。prices.updateactive トグルは決済フローの停止(可用性の毀損)。
  3. 列挙 → create の連鎖: list で得た customer ID と price ID をそのまま invoices.create の入力にできるため、外部からの ID 漏洩を前提とせず、列挙から請求作成までを無認証のまま一気に実行できる。
  4. 冪等キーの共有名前空間: idempotency_key は必須化済みだが完全にクライアント制御で、Stripe アカウント全体の共有名前空間のため衝突予測・妨害の余地が残る。
  5. レート制限なし: 外部 Stripe API を無制限に呼び出せ、レート枯渇・コストに波及し得る。invoices.create の確定失敗時にドラフト請求が残留する点も、ドラフトの大量生成に悪用され得る。

(出力の PII 露出・ネスト metadata 漏洩、traq_id の書き込み偽造は、allowlist 化と traq_id の出力撤去で対処済み。認可導入後も二重防御として維持する。)

やること

  • #16 が Context に注入した traQ ID・セッションを基に、認可プリンシパル(認証済みユーザー / 管理者)を導出する
  • pub とは別に、認可付きの base procedure(認証必須 / 管理者必須)を用意する
  • オブジェクト単位の認可にする(認証だけでなく、一般ユーザーは自分のオブジェクトのみアクセス可)
  • list / create の customer をセッションからサーバー側で導出する(クライアントの customer フィルタを認可根拠にしない)
  • ミューテーション(prices/products の更新、invoices の作成)を管理者・所有者に限定する
  • 管理者向けの一覧(invoices / checkout sessions / admin)を管理者必須へ
  • invoices.create に所有権検証・確定失敗時のクリーンアップ・冪等キーのサーバー側名前空間化を追加する
  • /rpc 手前(Nitro)または認可層でのレート制限

受け入れ条件

  • 管理者・ミューテーション・ユーザー系エンドポイントが無認証で実行できないこと
  • 一般ユーザーが他人のオブジェクトにアクセスできないこと(オブジェクト単位の認可)
  • list / create の対象 customer がクライアント指定ではなくセッションから導出されること

スコープ外/関連

  • 認証サブシステム(verify-email / csrf / session)自体は #16、traQ ID ↔ Stripe Customer の DB マッピングは #18。
  • 本 issue は現在の API 契約実装のスコープ外として切り出したもの。

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with packages/api/src/orpc.ts and the Context changes from #16. Trace how procedures currently use pub, then review the /rpc boundary in Nitro and the listed acceptance conditions. Done means unauthenticated access is blocked, object ownership is enforced, customers come from the session, and rate limiting is in place.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, authentication, authorization, backend, security
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.