receiver: inbox ログイン + CORS 制限で公開デプロイをハードニングする (#43 PR-2) - #103
Merged
Conversation
Issue #43 の確定設計(2026-07-05 壁打ち)に沿った挙動変更の本体。 - inbox にログインフォーム(GET/POST /login、POST /logout)を追加。 セッションは HMAC 派生 cookie(<expiry>.<HMAC(RECEIVER_TOKEN, expiry)>、 7 日、HttpOnly、SameSite=Lax、publicBaseUrl が https なら Secure)で、 生 token はブラウザに置かない。token 変更で全セッション即失効 - 操作系・閲覧系(inbox / feedback.json / screenshots)とも Bearer OR cookie を受ける。same-origin fetch は HttpOnly cookie が 自動で乗るため inbox.js は無改修 → RECEIVER_TOKEN 設定時に inbox の 全操作が 401 になる問題(ARCH-REVIEW F-1)を解消 - CORS を ingest(POST /feedback)のみに限定し、ALLOWED_ORIGINS / allowedOrigins の許可 origin 完全一致に制限。未設定は従来通り * + 起動ログ警告。inbox・操作系・screenshot は CORS ヘッダー自体を返さない - 受信 feedback に received: { origin, originAllowed } を保存 (#44 の ingest key までの弱い出所シグナル) - 認証有効時は GitHub issue body の screenshot 埋め込みをリンクのみに退化 (GitHub camo は cookie を送れないため) - inbox / login レスポンスに CSP と nosniff を付与 - README に公開デプロイ節(reverse proxy / HTTPS 終端 / secrets env 注入) 起動ログは設定サマリを先に出し「listening」を最終行に変更(起動完了の シグナルとしての意味を明確化し、テストからサマリを検証可能にする)。 Closes #43 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRdDjwxbAAaTMwwnzipkau
Owner
Author
🔍 レビュー依頼(→ Codex)
|
pathname だけで判定していたため GET /feedback などの 405 応答にも Access-Control-Allow-Origin が付いていた(Codex レビュー 🟡 指摘)。 method も一致条件に加え、405 では CORS を出さない回帰テストを追加。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRdDjwxbAAaTMwwnzipkau
Owner
Author
📋 レビュー結果(by Codex GPT-5.5)判定: ✅ merge 可(must 0 件) — 🟡 should 1 件(下記、対応済み)/ ⚪ nit 0 件 🔴 mustなし 🟡 should
⚪ nitなし レビュアーの検証範囲(要旨)route table / dispatch / HMAC cookie 検証 / CORS / login・logout / screenshot・feedback.json 保護を diff と実装の突き合わせで確認。inbox.js の same-origin fetch が cookie 認可で動くこと、テストの認証・cookie・CORS・405/OPTIONS/rate limit 回帰を実装と照合。read-only sandbox のためテスト実行は依頼元がローカルで代替( 依頼元対応
|
kosako
marked this pull request as ready for review
July 5, 2026 11:37
This was referenced Jul 5, 2026
kosako
added a commit
that referenced
this pull request
Jul 5, 2026
#103(inbox ログイン + CORS 制限)・#104(healthz / graceful shutdown / 設定警告)・#106(ingest key)で README.md に入れた receiver 契約の変更を 英語版にミラーする: - RECEIVER_TOKEN の説明を「閲覧系も保護 + inbox ログイン(HMAC cookie)」に更新 - INGEST_KEYS / ALLOWED_ORIGINS の項目を追加 - healthz・graceful shutdown・invalid setting warning を追記 - Public Deployment (EC2 etc.) 節を新設 - Init options に ingestKey を追加、Current Boundary の Auth 行を更新 Closes #105 Claude-Session: https://claude.ai/code/session_01LRdDjwxbAAaTMwwnzipkau Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
Issue #43(公開デプロイ時の receiver ハードニング)の PR-2。確定設計(2026-07-05 壁打ち)に沿った挙動変更の本体です。PR-1(#102、route table 純リファクタ)の上に載せています。
変更内容
inbox ブラウザ認証(ログインフォーム + HMAC cookie)
GET /login(フォーム)/POST /login(検証 + cookie 発行)/POST /logoutを追加<expiry>.<HMAC-SHA256(RECEIVER_TOKEN, expiry)>の派生値(有効期限 7 日、HttpOnly、SameSite=Lax、publicBaseUrlがhttps://ならSecure)。生 token はブラウザに保存されず、token ローテで全端末即失効node:cryptoのみで zero-dep 維持Bearer OR cookie(F-1 解消)
none/protected(401)/page(未認証ブラウザは /login へ 303)CORS の ingest 限定 + allowlist
POST /feedback(route table のcors: true)のみ。inbox・操作系・screenshot は同一オリジン利用のため CORS 自体を返さない(認証と二重の防壁)ALLOWED_ORIGINSenv /allowedOriginsconfig で許可 origin を完全一致制限。JSON POST は必ず preflight されるため、リスト外 origin のブラウザ投稿は本体 POST 前に遮断*+ 起動ログに警告(ゼロ設定ローカル互換)付随
received: { origin, originAllowed }を保存(弱シグナル。偽装不能な ingest key は Widget→Receiver 取り込みのペア認証と受信データの安全な取り扱い #44)。import bundle からの持ち込みは strip[Open screenshot]リンクのみに退化(camo が cookie を送れないため)default-src 'none'ベース)とnosniffRECEIVER_TOKEN/ALLOWED_ORIGINSの記述更新 + 「公開デプロイ(EC2 など)」節を新設listeningを最終行にテスト
npm run check全 100 件パス(新規 4 + 既存認証テスト更新 1 を含む)。実機スモーク済み: 未認証 inbox → /login 303 / 誤 token 401 / 正 token で cookie 発行 → inbox 200 / Bearer read 200 / allowlist echo + Vary / リスト外 origin に CORS ヘッダーなし / inbox に CORS なし / received メタデータ / logout で cookie 失効 / 405 + Allow。Closes #43
🤖 Generated with Claude Code
https://claude.ai/code/session_01LRdDjwxbAAaTMwwnzipkau