Skip to content

fix(federation): 署名者と actor の厳密な紐付けとオブジェクト起源の検証 - #292

Merged
sasagar merged 3 commits into
devfrom
fix/federation-actor-binding
Oct 14, 2026
Merged

sasagar merged 3 commits into
devfrom
fix/federation-actor-binding

Conversation

@sasagar

@sasagar sasagar commented Oct 14, 2026

Copy link
Copy Markdown
Member

変更

  • middleware/verifySignature.ts
    • validateKeyId(): http(s) 以外、ドットセグメント(%2e 含む)、バックスラッシュ、制御文字、ローカルホストを指す keyId を fetch 前に拒否
    • extractVerifiedPublicKey(): 取得したドキュメントの publicKey.id === keyId、owner === ドキュメント id、ドキュメント id が取得 URL と同一オリジンであることを検証(GoToSocial の /main-key スタブや /publickey 形式の Key ドキュメントにも対応)
    • キャッシュを {publicKeyPem, owner} に変更(旧形式はミス扱い)し、signatureActor をコンテキストに設定
  • utils/activityValidation.ts / routes/ap/inbox.ts: keyId.startsWith(actor) を廃止し、activity.actor === 検証済み owner を必須に。ローカルホストの actor は拒否
  • CreateHandler: attributedTo === actor と object.id が actor と同一オリジンの http(s) であることを必須に
  • AnnounceHandler: 取得したドキュメントの id が要求 URL と同一オリジンであること、attributedTo がローカルでないことを検証。uri が null の古いローカルノートは /notes/:id から引くように
  • RemoteNoteService.processNote: http(s) 以外の id を拒否、ローカル id では既存ノートを返すのみで作成しない、ローカルユーザー名義・id と作者のオリジン不一致を拒否
  • UpdateHandler / DeleteHandler: actor がローカルユーザーに解決される場合は拒否

互換性

  • Mastodon / Misskey / Pleroma / Akkoma / GoToSocial の鍵ドキュメント形式は引き続き受理(テストで確認)
  • ノート id と作者が別オリジンのサーバーは拒否されるようになる

確認

  • typecheck / lint / format:check / ユニットテスト 1071 件 pass

https://claude.ai/code/session_01Y29fBeRP344FME6de48wUv

…ce object origin

- verifySignature: validate keyId (http(s), no dot segments/backslashes,
  not local host), require fetched document's publicKey.id === keyId and
  owner === document id (or same-origin standalone Key doc), cache
  {publicKeyPem, owner} (legacy string entries treated as a miss), and
  expose the verified owner as c.get("signatureActor")
- activityValidation/inbox: replace keyId.startsWith(actor) with exact
  activity.actor === verified owner; reject local-host actors
- CreateHandler: require attributedTo === actor and same-origin http(s) id
- AnnounceHandler: require fetched id same-origin with requested URI,
  reject local authors, resolve local notes by id instead of self-fetch
- RemoteNoteService.processNote: reject non-http(s) ids (stored XSS via
  note.uri), local attributedTo, cross-origin id/author; return existing
  local note for local ids instead of creating
- Update/DeleteHandler: refuse to modify local users/notes
- Add unit tests for all of the above

Claude-Session: https://claude.ai/code/session_01Y29fBeRP344FME6de48wUv
@coderabbitai

coderabbitai Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 9 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository: Love-Rox/rox/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 9fe1bc69-1957-4092-86bf-7c77846fb11f
📥 Commits

Reviewing files that changed from the base of the PR and between 5474231 and 01687f1.

📒 Files selected for processing: 19
  • packages/backend/src/lib/safeFetch.ts
  • packages/backend/src/middleware/verifySignature.ts
  • packages/backend/src/routes/ap/inbox.ts
  • packages/backend/src/services/ap/RemoteActorService.ts
  • packages/backend/src/services/ap/RemoteFetchService.ts
  • packages/backend/src/services/ap/RemoteNoteService.ts
  • packages/backend/src/services/ap/inbox/handlers/AnnounceHandler.ts
  • packages/backend/src/services/ap/inbox/handlers/CreateHandler.ts
  • packages/backend/src/services/ap/inbox/handlers/DeleteHandler.ts
  • packages/backend/src/services/ap/inbox/handlers/UpdateHandler.ts
  • packages/backend/src/tests/unit/RemoteFetchService.redirect.test.ts
  • packages/backend/src/tests/unit/RemoteNoteService.test.ts
  • packages/backend/src/tests/unit/inbox-handlers/AnnounceHandler.test.ts
  • packages/backend/src/tests/unit/inbox-handlers/CreateHandler.test.ts
  • packages/backend/src/tests/unit/inbox-handlers/DeleteHandler.test.ts
  • packages/backend/src/tests/unit/inbox-handlers/UpdateHandler.test.ts
  • packages/backend/src/tests/unit/verifySignature.test.ts
  • packages/backend/src/utils/activityValidation.ts
  • packages/backend/src/utils/federationUrl.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

- verifySignature: replace same-origin trust with Mastodon-style owner
  verification. Accept the key document directly only when it is the
  owner's actor document served from exactly the requested URL (no
  redirect); otherwise fetch the owner actor (no redirect, id === owner)
  and require it to list a key with id === keyId and identical PEM.
  Covers GoToSocial /main-key stubs and /publickey Key documents.
- safeFetch: add safeFetchWithFinalUrl; RemoteFetchService exposes
  finalUrl and rejects cross-origin redirects by default
  (allowCrossOriginRedirect opt-in, used for WebFinger)
- AnnounceHandler: require fetched id === requested URI, otherwise
  refetch once by canonical id and require an exact match; reject
  cross-origin final URLs; reject non-public/home, localOnly or deleted
  targets; derive renote visibility from to/cc; require activity.id to be
  http(s) on the actor's origin
- activityValidation: activity.id must be http(s) and same origin as the
  actor (prevents javascript: ids and dedup/URI squatting)
- federationUrl/RemoteActorService: normalize hostnames (lowercase,
  trailing dot) for local-host detection
- Tests for all of the above

Claude-Session: https://claude.ai/code/session_01Y29fBeRP344FME6de48wUv
@sasagar

sasagar commented Oct 14, 2026

Copy link
Copy Markdown
Member Author

再レビューの指摘に対応しました(01687f1)。

  • 鍵の持ち主の actor ドキュメントを持ち主 URL から取得し、keyId と PEM の一致を確認する方式に変更(リダイレクトされた応答では省略しない)。AP オブジェクトの取得ではオリジンをまたぐリダイレクトを拒否(WebFinger を除く)
  • Announce: 取得したオブジェクトの id が要求 URL と一致しない場合は正規の id から再取得。対象が public/home 以外、localOnly、削除済みの場合は拒否。リノートの公開範囲を to/cc から決定
  • 全アクティビティで id が http(s) かつ actor と同一オリジンであることを必須に
  • ローカルホスト判定で大文字小文字と末尾ドットを正規化

https://claude.ai/code/session_01Y29fBeRP344FME6de48wUv

@sasagar
sasagar merged commit bbd1234 into dev Oct 14, 2026
11 checks passed
This was referenced Oct 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant