Skip to content

Release v2026.10.2 - #296

Merged
sasagar merged 19 commits into
mainfrom
dev
Oct 14, 2026
Merged

sasagar merged 19 commits into
mainfrom
dev

Conversation

@sasagar

@sasagar sasagar commented Oct 14, 2026

Copy link
Copy Markdown
Member

セキュリティ修正リリース。

含まれる変更(v2026.10.1 以降)

セルフホスト向けの注意

  • POST /api/users を削除しました。POST /api/auth/register を使用してください
  • リモートの SVG 画像はメディアプロキシ経由で表示されなくなります
  • ローカル/クラスタ内のインスタンスと連合する開発環境では ALLOW_PRIVATE_NETWORK_FETCH=true が必要です(本番では設定しないでください)
  • v2026.10.1 以前を公開していた場合、ユーザーの ActivityPub 鍵の再生成とパスワード変更を検討してください

https://claude.ai/code/session_01Y29fBeRP344FME6de48wUv

sasagar and others added 19 commits October 14, 2026 20:47
build-images.yml now calls ci.yml via workflow_call and the build job
needs it, so a failing commit no longer publishes :dev (which keel
auto-deploys). dev/main are excluded from ci.yml's push trigger to
avoid running CI twice.

Closes #288

Claude-Session: https://claude.ai/code/session_01Y29fBeRP344FME6de48wUv
Use a shared toPublicUser() helper so user responses never include
passwordHash, privateKey or email for other users, and sanitizeUser()
for the caller's own profile.

Claude-Session: https://claude.ai/code/session_01Y29fBeRP344FME6de48wUv
…-responses

fix(api): ユーザーレスポンスから非公開フィールドを除外
ci: CI 成功後にのみイメージをビルドする
- Remove image/svg+xml from the proxy allowlist; re-validate cached
  content types; add sandboxed CSP, nosniff and Content-Disposition to
  every proxy response; stop echoing upstream status/content-type
- /proxy/avatar now calls the proxy logic directly instead of
  self-fetching via the request Host
- securityHeaders no longer overwrites a route-specific CSP
- Add lib/safeFetch (isPrivateAddress, assertPublicUrl, safeFetch) with
  DNS resolution checks and per-hop redirect re-validation;
  ALLOW_PRIVATE_NETWORK_FETCH=true escape hatch for development
- Use safeFetch for ActivityPub object fetches, inbox delivery, WebPush,
  nodeinfo, instance icons, remote emoji import and Misskey API calls
- RemoteFetchService rejects non-JSON (activity/ld/json) responses;
  WebFinger accepts jrd+json

Claude-Session: 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
…egacy register, guard remote URLs

- OAuthService: never auto-link a provider login to an existing local account
  by email; refuse with "An account with this email already exists. Log in and
  link the provider from settings." Only verified provider emails are used
  (GitHub /user/emails verified, Google verified_email/email_verified, Discord
  verified); otherwise a placeholder email is stored.
- OAuth sign-up now honours registration.enabled, invite-only /
  REQUIRE_INVITATION, blocked usernames and the user:beforeRegister plugin hook.
  Already-linked users can still log in.
- routes/oauth: call requireAuth() (it was passed uncalled, so link/unlink/
  accounts never worked). Add POST /:provider/link/authorize; the link state
  cookie is bound to the initiating session token and the callback links to
  that session's user. POST /:provider/link requires matching state.
- unlinkAccount treats OAuth placeholder password hashes as no password.
- Extract registration policy helpers to lib/registrationPolicy.ts (shared by
  /api/auth/register and OAuth).
- Remove legacy POST /api/users, which bypassed all registration gating (unused
  by the frontend).
- Frontend: add toSafeHttpUrl and use it for remote note.uri in NoteCardMenu
  (open in new tab / copy / share) and MFM url/link nodes.

Claude-Session: https://claude.ai/code/session_01Y29fBeRP344FME6de48wUv
fix(security): メディアプロキシの SVG 配信停止と外部 fetch の SSRF 対策
…ed notes

Followers-only and specified (DM) notes were readable by anyone through
several endpoints. Introduce Misskey-compatible visibility rules and apply
them everywhere notes are returned.

- Add lib/noteVisibility.ts (canViewNote, isNoteVisibleTo, isPubliclyVisible)
- Add optional TimelineOptions.visibleTo filter to INoteRepository, implemented
  in pg, mysql and sqlite repositories (EXISTS on follows, mentions match,
  reply-target author)
- /api/notes/show, /user-notes, /replies: viewer-aware filtering (404 / empty)
- Home, social and list timelines: filter non-visible notes (list membership
  does not imply following); hydrated reply/renote targets are filtered too
- /api/mentions: apply viewer filter
- AP /notes/:id and outbox: serve only public/home, non-local-only notes with
  correct addressing for home (unlisted)
- oEmbed and reaction endpoints: hide non-public / non-visible notes
- Reject replies to invisible notes and renotes of others' non-public notes
- Stream pushes no longer embed non-public reply/renote targets; list
  notifications skip owners who cannot see the note
- Tests: unit tests for visibility rules, route-level tests, sqlite
  integration tests for the repository filter

Claude-Session: https://claude.ai/code/session_01Y29fBeRP344FME6de48wUv
fix(security): OAuth のメール自動リンク廃止・登録制限の統一・非 http URI の無害化
fix(security): フォロワー限定・ダイレクト投稿の公開範囲を全取得経路で適用
- 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
fix(federation): 署名者と actor の厳密な紐付けとオブジェクト起源の検証
@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 6 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: ed616f8d-8481-4a6e-ab23-5dcca7c43f90
📥 Commits

Reviewing files that changed from the base of the PR and between 755969e and 79338d0.

⛔ Files ignored due to path filters: 1
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing: 67
  • .env.example
  • .github/workflows/build-images.yml
  • .github/workflows/ci.yml
  • package.json
  • packages/backend/package.json
  • packages/backend/src/interfaces/repositories/INoteRepository.ts
  • packages/backend/src/lib/instance-icon.ts
  • packages/backend/src/lib/noteVisibility.ts
  • packages/backend/src/lib/registrationPolicy.ts
  • packages/backend/src/lib/routeUtils.ts
  • packages/backend/src/lib/safeFetch.ts
  • packages/backend/src/lib/validation.ts
  • packages/backend/src/middleware/securityHeaders.ts
  • packages/backend/src/middleware/verifySignature.ts
  • packages/backend/src/repositories/mysql/MysqlNoteRepository.ts
  • packages/backend/src/repositories/pg/PostgresNoteRepository.ts
  • packages/backend/src/repositories/sqlite/SqliteNoteRepository.ts
  • packages/backend/src/routes/ap/inbox.ts
  • packages/backend/src/routes/ap/note.ts
  • packages/backend/src/routes/ap/outbox.ts
  • packages/backend/src/routes/auth.ts
  • packages/backend/src/routes/emojis.ts
  • packages/backend/src/routes/following.ts
  • packages/backend/src/routes/mentions.ts
  • packages/backend/src/routes/notes.ts
  • packages/backend/src/routes/oauth.ts
  • packages/backend/src/routes/oembed.ts
  • packages/backend/src/routes/proxy.ts
  • packages/backend/src/routes/reactions.ts
  • packages/backend/src/routes/users.ts
  • packages/backend/src/services/ListService.ts
  • packages/backend/src/services/NoteService.ts
  • packages/backend/src/services/OAuthService.ts
  • packages/backend/src/services/RemoteInstanceRefreshService.ts
  • packages/backend/src/services/RemoteInstanceService.ts
  • packages/backend/src/services/WebPushService.ts
  • packages/backend/src/services/ap/ActivityDeliveryService.ts
  • packages/backend/src/services/ap/RemoteActorService.ts
  • packages/backend/src/services/ap/RemoteFetchService.ts
  • packages/backend/src/services/ap/RemoteLikesService.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/integration/sqlite-repositories.test.ts
  • packages/backend/src/tests/unit/NoteVisibilityRoutes.test.ts
  • packages/backend/src/tests/unit/OAuthRoutesSecurity.test.ts
  • packages/backend/src/tests/unit/OAuthService.test.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/noteVisibility.test.ts
  • packages/backend/src/tests/unit/proxy.test.ts
  • packages/backend/src/tests/unit/safeFetch.test.ts
  • packages/backend/src/tests/unit/verifySignature.test.ts
  • packages/backend/src/utils/activityValidation.ts
  • packages/backend/src/utils/federationUrl.ts
  • packages/frontend/package.json
  • packages/frontend/src/components/mfm/MfmRenderer.tsx
  • packages/frontend/src/components/note/NoteCardMenu.tsx
  • packages/frontend/src/lib/utils/safeUrl.ts
  • packages/frontend/src/tests/safeUrl.test.ts
  • packages/shared/package.json
  • 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.

@sasagar
sasagar merged commit 4a2e620 into main Oct 14, 2026
13 checks passed
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