Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

Missing access checks on caller-supplied video/space IDs (4 endpoints, PRs open)

オープン
#2,033 コメント 3 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
25/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
停滞
技術スタック
next.js, typescript

調査の方向性

開始する前にPR #2029–#2032を確認し、その後VideosPolicy.canView、getSpaceAccess、/api/analytics/route.ts、Analytics.tsxを読んで既存のチェックを理解してください。4つの記載されたエントリポイントが適切なアクセスチェックを実施し、拒否時にnot-foundレスポンスを返し、オープンなPRですでに対応されている作業を重複させなければ完了です。

索引モデルが issue の本文から書いたものです。

説明

While working on #1982 I audited every entry point in apps/web that accepts a caller-supplied resource ID, since that advisory looked like an instance of a pattern rather than a one-off. It was — I found four, and opened a PR for each.

The pattern

Cap has a solid access-control primitive in VideosPolicy.canView, and most code uses it. The failures all have the same shape: a second entry point to the same data that skips the check. Server actions are the main way this happens, because a "use server" function is independently callable by any client and does not inherit whatever gating its usual API route does.

What I found

PR Entry point State before Impact
#2029 newComment action authenticated only write comments/reactions into anyone's private video, notifying the owner
#2030 getVideoAnalytics action no auth at all read view counts of any private video
#2031 getSpaceVideoIds / getFolderVideoIds authenticated only enumerate video IDs in spaces of orgs you aren't in
#2032 /api/video/transcribe/status authenticated only read transcription status of anyone's private video

Two are worth calling out specifically:

#2030 is the sharpest. /api/analytics/route.ts does gate on canView, with a comment stating it exists so private view counts aren't disclosed. But getVideoAnalytics is a server action with zero auth of any kind — no getCurrentUser, no policy — and a "use client" component (Analytics.tsx) already calls it directly. The route's protection is bypassable by calling the action the same way the app's own client code does.

#2031 leaks IDs, which are the key to everything else. Video IDs are what /s/{videoId} and the other video endpoints take, so enumerating a private space's ID set is useful to an attacker even before any per-video check runs.

Sweep result

After these four, I re-swept: no remaining videoId-taking server action or API route in apps/web lacks an access check. Two files still show up in a naive grep but are fine on inspection — /api/notifications takes no ID and only returns the caller's own rows, and /api/tools/loom-download takes a Loom video ID, not a Cap resource.

Notes on the fixes

  • Every fix reuses an existing primitive (VideosPolicy.canView, or getSpaceAccess for the space paths) rather than introducing new logic, so they inherit the full existing model — owner, org, space, public, password, email-domain restrictions.
  • For #2031 I used getSpaceAccess and not requireSpaceManager: these are read paths, and requiring manager would have locked out ordinary members.
  • Denials return "not found" rather than "denied" throughout, so none of them become an oracle for which IDs exist.
  • Each PR is 1–2 files. They're independent and can be merged in any order.

Happy to consolidate them into a single PR if you'd prefer to review it that way.

cc @richiemcilroy

主要言語
Rust
スター
22.5k
フォーク
1.9k
平均マージ
6時間 33分
マージ済み PR(30日)
77

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

CapSoftware/Cap のほかの issue

CapSoftware/Cap の issue をすべて見る

似ている issue

Rust の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。