From 65c5626b65ee00d2663ec3604140a18427b65cdc Mon Sep 17 00:00:00 2001 From: syuilo Date: Tue, 14 Nov 2023 17:09:45 +0900 Subject: [PATCH 01/12] Merge pull request from GHSA-3f39-6537-3cgc This commit implements HTTP header and body validation to fix [SIF-2023-002](https://advisory.silicon.moe/advisory/sif-2023-002/) Signed-off-by: perillamint Co-authored-by: perillamint Co-authored-by: yunochi --- packages/backend/package.json | 3 +- .../src/server/ActivityPubServerService.ts | 58 ++++++++++++++++++- packages/backend/src/server/ServerService.ts | 8 +++ pnpm-lock.yaml | 16 ++++- 4 files changed, 79 insertions(+), 6 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index 3422489a10..c0e9016c91 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -59,7 +59,6 @@ "dependencies": { "@aws-sdk/client-s3": "3.412.0", "@aws-sdk/lib-storage": "3.412.0", - "@smithy/node-http-handler": "2.1.5", "@bull-board/api": "5.9.1", "@bull-board/fastify": "5.9.1", "@bull-board/ui": "5.9.1", @@ -78,6 +77,7 @@ "@peertube/http-signature": "1.7.0", "@simplewebauthn/server": "8.3.5", "@sinonjs/fake-timers": "11.2.2", + "@smithy/node-http-handler": "2.1.5", "@swc/cli": "0.1.62", "@swc/core": "1.3.96", "accepts": "1.3.8", @@ -99,6 +99,7 @@ "date-fns": "2.30.0", "deep-email-validator": "0.1.21", "fastify": "4.24.3", + "fastify-raw-body": "^4.2.2", "feed": "4.2.2", "file-type": "18.7.0", "fluent-ffmpeg": "2.1.2", diff --git a/packages/backend/src/server/ActivityPubServerService.ts b/packages/backend/src/server/ActivityPubServerService.ts index 2e64d41c91..17c503ef8e 100644 --- a/packages/backend/src/server/ActivityPubServerService.ts +++ b/packages/backend/src/server/ActivityPubServerService.ts @@ -3,6 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ +import * as crypto from 'node:crypto'; import { IncomingMessage } from 'node:http'; import { Inject, Injectable } from '@nestjs/common'; import fastifyAccepts from '@fastify/accepts'; @@ -108,7 +109,58 @@ export class ActivityPubServerService { return; } - // TODO: request.bodyのバリデーション? + if (signature.params.headers.indexOf('host') === -1 + || request.headers.host !== this.config.host) { + // Host not specified or not match. + reply.code(401); + return; + } + + if (signature.params.headers.indexOf('digest') === -1) { + // Digest not found. + reply.code(401); + } else { + const digest = request.headers.digest; + + if (typeof digest !== 'string') { + // Huh? + reply.code(401); + return; + } + + const re = /^([a-zA-Z0-9\-]+)=(.+)$/; + const match = digest.match(re); + + if (match == null) { + // Invalid digest + reply.code(401); + return; + } + + const algo = match[1]; + const digestValue = match[2]; + + if (algo !== 'SHA-256') { + // Unsupported digest algorithm + reply.code(401); + return; + } + + if (request.rawBody == null) { + // Bad request + reply.code(400); + return; + } + + const hash = crypto.createHash('sha256').update(request.rawBody).digest('base64'); + + if (hash !== digestValue) { + // Invalid digest + reply.code(401); + return; + } + } + this.queueService.inbox(request.body as IActivity, signature); reply.code(202); @@ -474,8 +526,8 @@ export class ActivityPubServerService { //#region Routing // inbox (limit: 64kb) - fastify.post('/inbox', { bodyLimit: 1024 * 64 }, async (request, reply) => await this.inbox(request, reply)); - fastify.post('/users/:user/inbox', { bodyLimit: 1024 * 64 }, async (request, reply) => await this.inbox(request, reply)); + fastify.post('/inbox', { config: { rawBody: true }, bodyLimit: 1024 * 64 }, async (request, reply) => await this.inbox(request, reply)); + fastify.post('/users/:user/inbox', { config: { rawBody: true }, bodyLimit: 1024 * 64 }, async (request, reply) => await this.inbox(request, reply)); // note fastify.get<{ Params: { note: string; } }>('/notes/:note', { constraints: { apOrHtml: 'ap' } }, async (request, reply) => { diff --git a/packages/backend/src/server/ServerService.ts b/packages/backend/src/server/ServerService.ts index 757cf21615..6e1956cd1d 100644 --- a/packages/backend/src/server/ServerService.ts +++ b/packages/backend/src/server/ServerService.ts @@ -9,6 +9,7 @@ import { fileURLToPath } from 'node:url'; import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common'; import Fastify, { FastifyInstance } from 'fastify'; import fastifyStatic from '@fastify/static'; +import fastifyRawBody from 'fastify-raw-body'; import { IsNull } from 'typeorm'; import { GlobalEventService } from '@/core/GlobalEventService.js'; import type { Config } from '@/config.js'; @@ -86,6 +87,13 @@ export class ServerService implements OnApplicationShutdown { }); } + // Register raw-body parser for ActivityPub HTTP signature validation. + fastify.register(fastifyRawBody, { + global: false, + encoding: 'utf-8', + runFirst: true, + }); + // Register non-serving static server so that the child services can use reply.sendFile. // `root` here is just a placeholder and each call must use its own `rootPath`. fastify.register(fastifyStatic, { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 846c36aaf7..db58506858 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,4 +1,4 @@ -lockfileVersion: '6.0' +lockfileVersion: '6.1' settings: autoInstallPeers: true @@ -182,6 +182,9 @@ importers: fastify: specifier: 4.24.3 version: 4.24.3 + fastify-raw-body: + specifier: ^4.2.2 + version: 4.2.2 feed: specifier: 4.2.2 version: 4.2.2 @@ -7001,7 +7004,7 @@ packages: hasBin: true peerDependencies: '@swc/core': ^1.2.66 - chokidar: 3.5.3 + chokidar: ^3.5.1 peerDependenciesMeta: chokidar: optional: true @@ -11727,6 +11730,15 @@ packages: resolution: {integrity: sha512-79ak0JxddO0utAXAQ5ccKhvs6vX2MGyHHMMsmZkBANrq3hXc1CHzvNPHOcvTsVMEPl5I+NT+RO4YKMGehOfSIg==} dev: false + /fastify-raw-body@4.2.2: + resolution: {integrity: sha512-6l4fXtxNn7WOQiylu5fv9/JfUTvWCg1ED4gF44hqnVesgttOXEUMnNkdV8ZxwufCstRyUYaYSBIN4VuRHDbJkw==} + engines: {node: '>= 10'} + dependencies: + fastify-plugin: 4.5.0 + raw-body: 2.5.2 + secure-json-parse: 2.7.0 + dev: false + /fastify@4.24.3: resolution: {integrity: sha512-6HHJ+R2x2LS3y1PqxnwEIjOTZxFl+8h4kSC/TuDPXtA+v2JnV9yEtOsNSKK1RMD7sIR2y1ZsA4BEFaid/cK5pg==} dependencies: From dfe4992e35d018e4e5c9664cd1ba28d8d00b8d3b Mon Sep 17 00:00:00 2001 From: syuilo Date: Tue, 14 Nov 2023 17:10:49 +0900 Subject: [PATCH 02/12] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c286fc3efc..6f45c32a62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ - Fix: トークンのないプラグインをアンインストールするときにエラーが出ないように - Fix: 投稿通知がオンでもダイレクト投稿はユーザーに通知されないようにされました - Fix: ユーザタイムラインの「ノート」選択時にリノートが混ざり込んでしまうことがある問題の修正 #12306 +- Fix: ActivityPubに関するセキュリティの向上 ## 2023.11.0 From dd533eb948a3ba533e452312e0f3915f37e5e06e Mon Sep 17 00:00:00 2001 From: syuilo Date: Tue, 14 Nov 2023 17:14:55 +0900 Subject: [PATCH 03/12] Update CHANGELOG.md --- CHANGELOG.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f45c32a62..9de4b0aae9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,11 +16,17 @@ ### General - Feat: コントロールパネルの「照会」から、入力されたメールアドレスを持つユーザーを検索できるようになりました +- Enhance: ローカリゼーションの更新 +- Enhance: 依存関係の更新 ### Client -- Fix: アイコンデコレーションが複数の場所で見切れている問題を修正 -― Fix: 「フォロー中の人全員の返信を含める/含めないようにする」のボタンを押下した際の確認が機能していない問題を修正 +- Enhance: プラグインでエラーが発生した場合のハンドリングを強化 +- Enhance: 細かなUIのブラッシュアップ +- Fix: プラグインでノートの表示を書き換えられない問題を修正 +- Fix: アイコンデコレーションが見切れる場合がある問題を修正 +- Fix: 「フォロー中の人全員の返信を含める/含めないようにする」のボタンを押下した際の確認が機能していない問題を修正 - Fix: 非ログイン時に「ノートを追加」を表示しないように変更 #12309 +- Fix: 絵文字ピッカーでの検索が更新されない問題を修正 ### Server - Fix: トークンのないプラグインをアンインストールするときにエラーが出ないように From d2906d4628a9a36fcb1ad868f21025a7a131e0f7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Nov 2023 21:19:26 +0900 Subject: [PATCH 04/12] build(deps): bump actions/github-script from 6 to 7 (#12328) Bumps [actions/github-script](https://github.com/actions/github-script) from 6 to 7. - [Release notes](https://github.com/actions/github-script/releases) - [Commits](https://github.com/actions/github-script/compare/v6...v7) --- updated-dependencies: - dependency-name: actions/github-script dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/pr-preview-deploy.yml | 6 +++--- .github/workflows/pr-preview-destroy.yml | 2 +- .github/workflows/report-api-diff.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pr-preview-deploy.yml b/.github/workflows/pr-preview-deploy.yml index 0e76bdeb2f..cb9a4ebfc8 100644 --- a/.github/workflows/pr-preview-deploy.yml +++ b/.github/workflows/pr-preview-deploy.yml @@ -13,7 +13,7 @@ jobs: github.event.client_payload.slash_command.sha != '' && contains(github.event.client_payload.pull_request.head.sha, github.event.client_payload.slash_command.sha) steps: - - uses: actions/github-script@v6.3.3 + - uses: actions/github-script@v7 id: check-id env: number: ${{ github.event.client_payload.pull_request.number }} @@ -37,7 +37,7 @@ jobs: return check[0].id; - - uses: actions/github-script@v6.3.3 + - uses: actions/github-script@v7 env: check_id: ${{ steps.check-id.outputs.result }} details_url: ${{ github.server_url }}/${{ github.repository }}/runs/${{ github.run_id }} @@ -72,7 +72,7 @@ jobs: timeout: 15m # Update check run called "integration-fork" - - uses: actions/github-script@v6.3.3 + - uses: actions/github-script@v7 id: update-check-run if: ${{ always() }} env: diff --git a/.github/workflows/pr-preview-destroy.yml b/.github/workflows/pr-preview-destroy.yml index 8adfad9dab..47d9eb313a 100644 --- a/.github/workflows/pr-preview-destroy.yml +++ b/.github/workflows/pr-preview-destroy.yml @@ -10,7 +10,7 @@ jobs: destroy-preview-environment: runs-on: ubuntu-latest steps: - - uses: actions/github-script@v6.3.3 + - uses: actions/github-script@v7 id: check-conclusion env: number: ${{ github.event.number }} diff --git a/.github/workflows/report-api-diff.yml b/.github/workflows/report-api-diff.yml index 55d13100fb..2868d6cc09 100644 --- a/.github/workflows/report-api-diff.yml +++ b/.github/workflows/report-api-diff.yml @@ -16,7 +16,7 @@ jobs: # api-artifact steps: - name: Download artifact - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: script: | let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ From 5cb24e84700cba0d23d2c4f46fcc121aab3209d3 Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 15 Nov 2023 11:07:10 +0900 Subject: [PATCH 05/12] update pnpm --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cc765f09ba..1369249260 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "type": "git", "url": "https://github.com/misskey-dev/misskey.git" }, - "packageManager": "pnpm@8.10.0", + "packageManager": "pnpm@8.10.5", "workspaces": [ "packages/frontend", "packages/backend", From 3939360e5569e6a3b851f89616ff2bed1b72fb41 Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 15 Nov 2023 11:09:54 +0900 Subject: [PATCH 06/12] =?UTF-8?q?fix(frontend):=20=E7=89=B9=E5=AE=9A?= =?UTF-8?q?=E3=81=AE=E6=9D=A1=E4=BB=B6=E4=B8=8B=E3=81=A7=E3=83=8E=E3=83=BC?= =?UTF-8?q?=E3=83=88=E3=81=8Cnyaize=E3=81=95=E3=82=8C=E3=81=AA=E3=81=84?= =?UTF-8?q?=E5=95=8F=E9=A1=8C=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix #12331 --- CHANGELOG.md | 1 + packages/frontend/src/components/MkNote.vue | 8 ++++---- packages/frontend/src/components/MkNoteDetailed.vue | 6 +++--- packages/frontend/src/components/MkNotePreview.vue | 2 +- packages/frontend/src/components/MkNoteSimple.vue | 2 +- packages/frontend/src/components/MkNoteSub.vue | 2 +- packages/frontend/src/components/MkSubNoteContent.vue | 2 +- .../src/components/global/MkMisskeyFlavoredMarkdown.ts | 4 ++-- 8 files changed, 14 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9de4b0aae9..6e32249ee7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ - Fix: 「フォロー中の人全員の返信を含める/含めないようにする」のボタンを押下した際の確認が機能していない問題を修正 - Fix: 非ログイン時に「ノートを追加」を表示しないように変更 #12309 - Fix: 絵文字ピッカーでの検索が更新されない問題を修正 +- Fix: 特定の条件下でノートがnyaizeされない問題を修正 ### Server - Fix: トークンのないプラグインをアンインストールするときにエラーが出ないように diff --git a/packages/frontend/src/components/MkNote.vue b/packages/frontend/src/components/MkNote.vue index 7e8b4c9b2b..e300ef88a5 100644 --- a/packages/frontend/src/components/MkNote.vue +++ b/packages/frontend/src/components/MkNote.vue @@ -43,7 +43,7 @@ SPDX-License-Identifier: AGPL-3.0-only
- +
@@ -53,7 +53,7 @@ SPDX-License-Identifier: AGPL-3.0-only

- +

@@ -65,7 +65,7 @@ SPDX-License-Identifier: AGPL-3.0-only :parsedNodes="parsed" :text="appearNote.text" :author="appearNote.user" - :nyaize="'account'" + :nyaize="'respect'" :emojiUrls="appearNote.emojis" :enableEmojiMenu="true" :enableEmojiMenuReaction="true" @@ -74,7 +74,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.t('translatedFrom', { x: translation.sourceLang }) }}: - +
diff --git a/packages/frontend/src/components/MkNoteDetailed.vue b/packages/frontend/src/components/MkNoteDetailed.vue index 920debc884..d1bc3f676f 100644 --- a/packages/frontend/src/components/MkNoteDetailed.vue +++ b/packages/frontend/src/components/MkNoteDetailed.vue @@ -67,7 +67,7 @@ SPDX-License-Identifier: AGPL-3.0-only

- +

@@ -78,7 +78,7 @@ SPDX-License-Identifier: AGPL-3.0-only :parsedNodes="parsed" :text="appearNote.text" :author="appearNote.user" - :nyaize="'account'" + :nyaize="'respect'" :emojiUrls="appearNote.emojis" :enableEmojiMenu="true" :enableEmojiMenuReaction="true" @@ -88,7 +88,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.t('translatedFrom', { x: translation.sourceLang }) }}: - +
diff --git a/packages/frontend/src/components/MkNotePreview.vue b/packages/frontend/src/components/MkNotePreview.vue index 79ce60baff..9b7a39b537 100644 --- a/packages/frontend/src/components/MkNotePreview.vue +++ b/packages/frontend/src/components/MkNotePreview.vue @@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only
- +
diff --git a/packages/frontend/src/components/MkNoteSimple.vue b/packages/frontend/src/components/MkNoteSimple.vue index 28b00af246..a40dcaf003 100644 --- a/packages/frontend/src/components/MkNoteSimple.vue +++ b/packages/frontend/src/components/MkNoteSimple.vue @@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only

- +

diff --git a/packages/frontend/src/components/MkNoteSub.vue b/packages/frontend/src/components/MkNoteSub.vue index f61b963d9b..422e9094cc 100644 --- a/packages/frontend/src/components/MkNoteSub.vue +++ b/packages/frontend/src/components/MkNoteSub.vue @@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only

- +

diff --git a/packages/frontend/src/components/MkSubNoteContent.vue b/packages/frontend/src/components/MkSubNoteContent.vue index e9f2b838d2..638407872f 100644 --- a/packages/frontend/src/components/MkSubNoteContent.vue +++ b/packages/frontend/src/components/MkSubNoteContent.vue @@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only ({{ i18n.ts.private }}) ({{ i18n.ts.deleted }}) - + RN: ...
diff --git a/packages/frontend/src/components/global/MkMisskeyFlavoredMarkdown.ts b/packages/frontend/src/components/global/MkMisskeyFlavoredMarkdown.ts index 441731d7ca..d14a1fb63c 100644 --- a/packages/frontend/src/components/global/MkMisskeyFlavoredMarkdown.ts +++ b/packages/frontend/src/components/global/MkMisskeyFlavoredMarkdown.ts @@ -36,7 +36,7 @@ type MfmProps = { isNote?: boolean; emojiUrls?: string[]; rootScale?: number; - nyaize: boolean | 'account'; + nyaize: boolean | 'respect'; parsedNodes?: mfm.MfmNode[] | null; enableEmojiMenu?: boolean; enableEmojiMenuReaction?: boolean; @@ -45,7 +45,7 @@ type MfmProps = { // eslint-disable-next-line import/no-default-export export default function(props: MfmProps) { const isNote = props.isNote ?? true; - const shouldNyaize = props.nyaize ? props.nyaize === 'account' ? props.author?.isCat : false : false; + const shouldNyaize = props.nyaize ? props.nyaize === 'respect' ? props.author?.isCat : false : false; // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (props.text == null || props.text === '') return; From aa6d0d4359d58a8295c60a79c44ab0dfe094b04e Mon Sep 17 00:00:00 2001 From: zyoshoka <107108195+zyoshoka@users.noreply.github.com> Date: Wed, 15 Nov 2023 11:10:45 +0900 Subject: [PATCH 07/12] =?UTF-8?q?fix(backend):=20=E9=9D=9E=E5=85=AC?= =?UTF-8?q?=E9=96=8B=E3=81=AE=E6=8A=95=E7=A8=BF=E3=81=AB=E5=AF=BE=E3=81=97?= =?UTF-8?q?=E3=81=A6=E8=BF=94=E4=BF=A1=E3=81=A7=E3=81=8D=E3=81=AA=E3=81=84?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=20(#12333)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(backend): 非公開の投稿に対して返信できないように * Update CHANGELOG.md * fix: test --- CHANGELOG.md | 1 + packages/backend/src/server/api/endpoints/notes/create.ts | 8 ++++++++ packages/backend/test/e2e/timelines.ts | 1 + 3 files changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e32249ee7..c08cb036f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ - Fix: 投稿通知がオンでもダイレクト投稿はユーザーに通知されないようにされました - Fix: ユーザタイムラインの「ノート」選択時にリノートが混ざり込んでしまうことがある問題の修正 #12306 - Fix: ActivityPubに関するセキュリティの向上 +- Fix: 非公開の投稿に対して返信できないように ## 2023.11.0 diff --git a/packages/backend/src/server/api/endpoints/notes/create.ts b/packages/backend/src/server/api/endpoints/notes/create.ts index df02d3acb7..513b77b98a 100644 --- a/packages/backend/src/server/api/endpoints/notes/create.ts +++ b/packages/backend/src/server/api/endpoints/notes/create.ts @@ -70,6 +70,12 @@ export const meta = { id: '749ee0f6-d3da-459a-bf02-282e2da4292c', }, + cannotReplyToInvisibleNote: { + message: 'You cannot reply to an invisible Note.', + code: 'CANNOT_REPLY_TO_AN_INVISIBLE_NOTE', + id: 'b98980fa-3780-406c-a935-b6d0eeee10d1', + }, + cannotReplyToPureRenote: { message: 'You can not reply to a pure Renote.', code: 'CANNOT_REPLY_TO_A_PURE_RENOTE', @@ -276,6 +282,8 @@ export default class extends Endpoint { // eslint- throw new ApiError(meta.errors.noSuchReplyTarget); } else if (isPureRenote(reply)) { throw new ApiError(meta.errors.cannotReplyToPureRenote); + } else if (!await this.noteEntityService.isVisibleForMe(reply, me.id)) { + throw new ApiError(meta.errors.cannotReplyToInvisibleNote); } // Check blocking diff --git a/packages/backend/test/e2e/timelines.ts b/packages/backend/test/e2e/timelines.ts index 760bb8a574..73c446444b 100644 --- a/packages/backend/test/e2e/timelines.ts +++ b/packages/backend/test/e2e/timelines.ts @@ -152,6 +152,7 @@ describe('Timelines', () => { await api('/following/create', { userId: bob.id }, alice); await api('/following/create', { userId: carol.id }, alice); + await api('/following/create', { userId: carol.id }, bob); await api('/following/update', { userId: bob.id, withReplies: true }, alice); await sleep(1000); const carolNote = await post(carol, { text: 'hi', visibility: 'followers' }); From 04075ee0bede198452dcd5e8ca6a00a3b750208b Mon Sep 17 00:00:00 2001 From: Jaehong Kang Date: Wed, 15 Nov 2023 11:13:34 +0900 Subject: [PATCH 08/12] enhance(backend): Implementation of HTTP header and body validation to fix SIF-2023-002 (#12334) Using Buffer instead of string Co-authored-by: perillamint --- packages/backend/package.json | 1 + .../src/server/ActivityPubServerService.ts | 26 ++++++++++++++++--- packages/backend/src/server/ServerService.ts | 4 +-- pnpm-lock.yaml | 3 +++ 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index c0e9016c91..beb9661fa1 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -151,6 +151,7 @@ "rss-parser": "3.13.0", "rxjs": "7.8.1", "sanitize-html": "2.11.0", + "secure-json-parse": "^2.4.0", "sharp": "0.32.6", "sharp-read-bmp": "github:misskey-dev/sharp-read-bmp", "slacc": "0.0.10", diff --git a/packages/backend/src/server/ActivityPubServerService.ts b/packages/backend/src/server/ActivityPubServerService.ts index 17c503ef8e..2c9e2cf24f 100644 --- a/packages/backend/src/server/ActivityPubServerService.ts +++ b/packages/backend/src/server/ActivityPubServerService.ts @@ -11,6 +11,7 @@ import httpSignature from '@peertube/http-signature'; import { Brackets, In, IsNull, LessThan, Not } from 'typeorm'; import accepts from 'accepts'; import vary from 'vary'; +import secureJson from 'secure-json-parse'; import { DI } from '@/di-symbols.js'; import type { FollowingsRepository, NotesRepository, EmojisRepository, NoteReactionsRepository, UserProfilesRepository, UserNotePiningsRepository, UsersRepository, FollowRequestsRepository } from '@/models/_.js'; import * as url from '@/misc/prelude/url.js'; @@ -28,7 +29,7 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { bindThis } from '@/decorators.js'; import { IActivity } from '@/core/activitypub/type.js'; import { isPureRenote } from '@/misc/is-pure-renote.js'; -import type { FastifyInstance, FastifyRequest, FastifyReply, FastifyPluginOptions } from 'fastify'; +import type { FastifyInstance, FastifyRequest, FastifyReply, FastifyPluginOptions, FastifyBodyParser } from 'fastify'; import type { FindOptionsWhere } from 'typeorm'; const ACTIVITY_JSON = 'application/activity+json; charset=utf-8'; @@ -512,9 +513,28 @@ export class ActivityPubServerService { }, }); + const almostDefaultJsonParser: FastifyBodyParser = function (request, rawBody, done) { + if (rawBody.length === 0) { + const err = new Error('Body cannot be empty!') as any; + err.statusCode = 400; + return done(err); + } + + try { + const json = secureJson.parse(rawBody.toString('utf8'), null, { + protoAction: 'ignore', + constructorAction: 'ignore', + }); + done(null, json); + } catch (err: any) { + err.statusCode = 400; + return done(err); + } + }; + fastify.register(fastifyAccepts); - fastify.addContentTypeParser('application/activity+json', { parseAs: 'string' }, fastify.getDefaultJsonParser('ignore', 'ignore')); - fastify.addContentTypeParser('application/ld+json', { parseAs: 'string' }, fastify.getDefaultJsonParser('ignore', 'ignore')); + fastify.addContentTypeParser('application/activity+json', { parseAs: 'buffer' }, almostDefaultJsonParser); + fastify.addContentTypeParser('application/ld+json', { parseAs: 'buffer' }, almostDefaultJsonParser); fastify.addHook('onRequest', (request, reply, done) => { reply.header('Access-Control-Allow-Headers', 'Accept'); diff --git a/packages/backend/src/server/ServerService.ts b/packages/backend/src/server/ServerService.ts index 6e1956cd1d..17c2a93525 100644 --- a/packages/backend/src/server/ServerService.ts +++ b/packages/backend/src/server/ServerService.ts @@ -88,9 +88,9 @@ export class ServerService implements OnApplicationShutdown { } // Register raw-body parser for ActivityPub HTTP signature validation. - fastify.register(fastifyRawBody, { + await fastify.register(fastifyRawBody, { global: false, - encoding: 'utf-8', + encoding: null, runFirst: true, }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index db58506858..f483eacfd6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -338,6 +338,9 @@ importers: sanitize-html: specifier: 2.11.0 version: 2.11.0 + secure-json-parse: + specifier: ^2.4.0 + version: 2.7.0 sharp: specifier: 0.32.6 version: 0.32.6 From 6cc0685f2af85d2eead26667430592eab6068aab Mon Sep 17 00:00:00 2001 From: atsuchan <83960488+atsu1125@users.noreply.github.com> Date: Wed, 15 Nov 2023 11:14:27 +0900 Subject: [PATCH 09/12] =?UTF-8?q?Fix(frontend):=20=E3=82=B5=E3=83=BC?= =?UTF-8?q?=E3=83=90=E3=83=BC=E3=82=B5=E3=82=A4=E3=83=AC=E3=83=B3=E3=82=B9?= =?UTF-8?q?=20(#12292)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/pages/admin/federation.vue | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/frontend/src/pages/admin/federation.vue b/packages/frontend/src/pages/admin/federation.vue index 7dc0b46946..41849894ea 100644 --- a/packages/frontend/src/pages/admin/federation.vue +++ b/packages/frontend/src/pages/admin/federation.vue @@ -23,6 +23,7 @@ SPDX-License-Identifier: AGPL-3.0-only + @@ -83,6 +84,7 @@ const pagination = { state === 'publishing' ? { publishing: true } : state === 'suspended' ? { suspended: true } : state === 'blocked' ? { blocked: true } : + state === 'silenced' ? { silenced: true } : state === 'notResponding' ? { notResponding: true } : {}), })), @@ -91,6 +93,7 @@ const pagination = { function getStatus(instance) { if (instance.isSuspended) return 'Suspended'; if (instance.isBlocked) return 'Blocked'; + if (instance.isSilenced) return 'Silenced'; if (instance.isNotResponding) return 'Error'; return 'Alive'; } From 96f1728573204498482b2a8424ad789dc038c205 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8A=E3=81=95=E3=82=80=E3=81=AE=E3=81=B2=E3=81=A8?= <46447427+samunohito@users.noreply.github.com> Date: Wed, 15 Nov 2023 11:24:54 +0900 Subject: [PATCH 10/12] =?UTF-8?q?fix:=20=E8=A1=A8=E7=A4=BA=E6=B8=88?= =?UTF-8?q?=E3=81=BF=E3=81=AE=E3=82=AB=E3=83=A9=E3=83=A0=E3=81=8B=E3=82=89?= =?UTF-8?q?=E5=88=A5=E3=81=AE=E3=83=81=E3=83=A3=E3=83=B3=E3=83=8D=E3=83=AB?= =?UTF-8?q?=E3=82=92=E9=81=B8=E6=8A=9E=E3=81=97=E3=81=9F=E6=99=82=E3=80=81?= =?UTF-8?q?=E3=82=BF=E3=82=A4=E3=83=A0=E3=83=A9=E3=82=A4=E3=83=B3=E3=81=AE?= =?UTF-8?q?=E5=86=85=E5=AE=B9=E3=81=8C=E8=BF=BD=E5=BE=93=E3=81=97=E3=81=A6?= =?UTF-8?q?=E5=A4=89=E6=9B=B4=E3=81=95=E3=82=8C=E3=81=AA=E3=81=84=E5=95=8F?= =?UTF-8?q?=E9=A1=8C=E3=81=AB=E5=AF=BE=E5=87=A6=20(#12237)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 表示済みのカラムから別のチャンネルを選択した時、タイムラインの内容が追従して変更されない問題に対処 * fix CHANGELOG.md * fix code style * Update MkTimeline.vue * コメント対応(MkButtonのimportとonBeforeUpdate->watch) * fix CHANGELOG.md * Update MkPagination.vue --------- Co-authored-by: osamu <46447427+sam-osamu@users.noreply.github.com> Co-authored-by: syuilo --- CHANGELOG.md | 1 + .../frontend/src/components/MkPagination.vue | 16 +- .../frontend/src/components/MkTimeline.vue | 198 +++++++++++------- 3 files changed, 130 insertions(+), 85 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c08cb036f7..42cc4e137b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ ### Client - Enhance: プラグインでエラーが発生した場合のハンドリングを強化 - Enhance: 細かなUIのブラッシュアップ +- Fix: デッキに表示されたチャンネルの表示先チャンネルを切り替えた際、即座に反映されない問題を修正 #12236 - Fix: プラグインでノートの表示を書き換えられない問題を修正 - Fix: アイコンデコレーションが見切れる場合がある問題を修正 - Fix: 「フォロー中の人全員の返信を含める/含めないようにする」のボタンを押下した際の確認が機能していない問題を修正 diff --git a/packages/frontend/src/components/MkPagination.vue b/packages/frontend/src/components/MkPagination.vue index 5643de7683..e7796dfcb5 100644 --- a/packages/frontend/src/components/MkPagination.vue +++ b/packages/frontend/src/components/MkPagination.vue @@ -43,12 +43,11 @@ SPDX-License-Identifier: AGPL-3.0-only