Compare commits

...

4 Commits

Author SHA1 Message Date
syuilo dd533eb948 Update CHANGELOG.md 2023-11-14 17:14:55 +09:00
syuilo dfe4992e35 Update CHANGELOG.md 2023-11-14 17:10:49 +09:00
syuilo 65c5626b65
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 <perillamint@silicon.moe>
Co-authored-by: perillamint <perillamint@silicon.moe>
Co-authored-by: yunochi <yuno@yunochi.com>
2023-11-14 17:09:45 +09:00
syuilo 30bb24d18c update deps 2023-11-14 10:35:48 +09:00
9 changed files with 1240 additions and 1023 deletions

View File

@ -16,16 +16,23 @@
### General
- Feat: コントロールパネルの「照会」から、入力されたメールアドレスを持つユーザーを検索できるようになりました
- Enhance: ローカリゼーションの更新
- Enhance: 依存関係の更新
### Client
- Fix: アイコンデコレーションが複数の場所で見切れている問題を修正
― Fix: 「フォロー中の人全員の返信を含める/含めないようにする」のボタンを押下した際の確認が機能していない問題を修正
- Enhance: プラグインでエラーが発生した場合のハンドリングを強化
- Enhance: 細かなUIのブラッシュアップ
- Fix: プラグインでノートの表示を書き換えられない問題を修正
- Fix: アイコンデコレーションが見切れる場合がある問題を修正
- Fix: 「フォロー中の人全員の返信を含める/含めないようにする」のボタンを押下した際の確認が機能していない問題を修正
- Fix: 非ログイン時に「ノートを追加」を表示しないように変更 #12309
- Fix: 絵文字ピッカーでの検索が更新されない問題を修正
### Server
- Fix: トークンのないプラグインをアンインストールするときにエラーが出ないように
- Fix: 投稿通知がオンでもダイレクト投稿はユーザーに通知されないようにされました
- Fix: ユーザタイムラインの「ノート」選択時にリノートが混ざり込んでしまうことがある問題の修正 #12306
- Fix: ActivityPubに関するセキュリティの向上
## 2023.11.0

View File

@ -52,12 +52,12 @@
"typescript": "5.2.2"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "6.9.1",
"@typescript-eslint/parser": "6.9.1",
"@typescript-eslint/eslint-plugin": "6.11.0",
"@typescript-eslint/parser": "6.11.0",
"cross-env": "7.0.3",
"cypress": "13.4.0",
"eslint": "8.52.0",
"start-server-and-test": "2.0.1"
"cypress": "13.5.0",
"eslint": "8.53.0",
"start-server-and-test": "2.0.2"
},
"optionalDependencies": {
"@tensorflow/tfjs-core": "4.4.0"

View File

@ -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",
@ -68,7 +67,7 @@
"@fastify/cookie": "9.1.0",
"@fastify/cors": "8.4.1",
"@fastify/express": "2.3.0",
"@fastify/http-proxy": "9.2.1",
"@fastify/http-proxy": "9.3.0",
"@fastify/multipart": "8.0.0",
"@fastify/static": "6.12.0",
"@fastify/view": "8.2.0",
@ -78,8 +77,9 @@
"@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.95",
"@swc/core": "1.3.96",
"accepts": "1.3.8",
"ajv": "8.12.0",
"archiver": "6.0.1",
@ -87,7 +87,7 @@
"bcryptjs": "2.4.3",
"blurhash": "2.0.5",
"body-parser": "1.20.2",
"bullmq": "4.12.8",
"bullmq": "4.13.2",
"cacheable-lookup": "7.0.0",
"cbor": "9.0.1",
"chalk": "5.3.0",
@ -99,8 +99,9 @@
"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.6.0",
"file-type": "18.7.0",
"fluent-ffmpeg": "2.1.2",
"form-data": "4.0.0",
"got": "13.0.0",
@ -122,7 +123,7 @@
"mime-types": "2.1.35",
"misskey-js": "workspace:*",
"ms": "3.0.0-canary.1",
"nanoid": "5.0.2",
"nanoid": "5.0.3",
"nested-property": "4.0.0",
"node-fetch": "3.3.2",
"nodemailer": "6.9.7",
@ -156,7 +157,7 @@
"strict-event-emitter-types": "2.0.0",
"stringz": "2.1.0",
"summaly": "github:misskey-dev/summaly",
"systeminformation": "5.21.15",
"systeminformation": "5.21.17",
"tinycolor2": "1.6.0",
"tmp": "0.2.1",
"tsc-alias": "1.8.8",
@ -174,50 +175,50 @@
"@jest/globals": "29.7.0",
"@simplewebauthn/typescript-types": "8.3.4",
"@swc/jest": "0.2.29",
"@types/accepts": "1.3.6",
"@types/archiver": "6.0.0",
"@types/bcryptjs": "2.4.5",
"@types/body-parser": "1.19.4",
"@types/accepts": "1.3.7",
"@types/archiver": "6.0.1",
"@types/bcryptjs": "2.4.6",
"@types/body-parser": "1.19.5",
"@types/cbor": "6.0.0",
"@types/color-convert": "2.0.2",
"@types/content-disposition": "0.5.7",
"@types/fluent-ffmpeg": "2.1.23",
"@types/http-link-header": "1.0.4",
"@types/jest": "29.5.7",
"@types/js-yaml": "4.0.8",
"@types/jsdom": "21.1.4",
"@types/jsonld": "1.5.11",
"@types/jsrsasign": "10.5.11",
"@types/mime-types": "2.1.3",
"@types/ms": "0.7.33",
"@types/node": "20.8.10",
"@types/color-convert": "2.0.3",
"@types/content-disposition": "0.5.8",
"@types/fluent-ffmpeg": "2.1.24",
"@types/http-link-header": "1.0.5",
"@types/jest": "29.5.8",
"@types/js-yaml": "4.0.9",
"@types/jsdom": "21.1.5",
"@types/jsonld": "1.5.12",
"@types/jsrsasign": "10.5.12",
"@types/mime-types": "2.1.4",
"@types/ms": "0.7.34",
"@types/node": "20.9.0",
"@types/node-fetch": "3.0.3",
"@types/nodemailer": "6.4.13",
"@types/oauth": "0.9.3",
"@types/oauth2orize": "1.11.2",
"@types/oauth2orize-pkce": "0.1.1",
"@types/pg": "8.10.7",
"@types/pug": "2.0.8",
"@types/punycode": "2.1.1",
"@types/qrcode": "1.5.4",
"@types/random-seed": "0.3.4",
"@types/ratelimiter": "3.4.5",
"@types/rename": "1.0.6",
"@types/sanitize-html": "2.9.3",
"@types/semver": "7.5.4",
"@types/nodemailer": "6.4.14",
"@types/oauth": "0.9.4",
"@types/oauth2orize": "1.11.3",
"@types/oauth2orize-pkce": "0.1.2",
"@types/pg": "8.10.9",
"@types/pug": "2.0.9",
"@types/punycode": "2.1.2",
"@types/qrcode": "1.5.5",
"@types/random-seed": "0.3.5",
"@types/ratelimiter": "3.4.6",
"@types/rename": "1.0.7",
"@types/sanitize-html": "2.9.4",
"@types/semver": "7.5.5",
"@types/sharp": "0.32.0",
"@types/simple-oauth2": "5.0.6",
"@types/sinonjs__fake-timers": "8.1.4",
"@types/tinycolor2": "1.4.5",
"@types/tmp": "0.2.5",
"@types/vary": "1.1.2",
"@types/web-push": "3.6.2",
"@types/ws": "8.5.8",
"@typescript-eslint/eslint-plugin": "6.9.1",
"@typescript-eslint/parser": "6.9.1",
"@types/simple-oauth2": "5.0.7",
"@types/sinonjs__fake-timers": "8.1.5",
"@types/tinycolor2": "1.4.6",
"@types/tmp": "0.2.6",
"@types/vary": "1.1.3",
"@types/web-push": "3.6.3",
"@types/ws": "8.5.9",
"@typescript-eslint/eslint-plugin": "6.11.0",
"@typescript-eslint/parser": "6.11.0",
"aws-sdk-client-mock": "3.0.0",
"cross-env": "7.0.3",
"eslint": "8.52.0",
"eslint": "8.53.0",
"eslint-plugin-import": "2.29.0",
"execa": "8.0.1",
"jest": "29.7.0",

View File

@ -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) => {

View File

@ -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, {

View File

@ -24,9 +24,9 @@
"@rollup/pluginutils": "5.0.5",
"@syuilo/aiscript": "0.16.0",
"@tabler/icons-webfont": "2.37.0",
"@vitejs/plugin-vue": "4.4.0",
"@vitejs/plugin-vue": "4.4.1",
"@vue-macros/reactivity-transform": "0.3.23",
"@vue/compiler-sfc": "3.3.7",
"@vue/compiler-sfc": "3.3.8",
"astring": "1.8.6",
"autosize": "6.0.1",
"aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.0.6",
@ -39,7 +39,7 @@
"chartjs-chart-matrix": "2.0.1",
"chartjs-plugin-gradient": "0.6.1",
"chartjs-plugin-zoom": "2.0.1",
"chromatic": "7.6.0",
"chromatic": "9.0.0",
"compare-versions": "6.1.0",
"cropperjs": "2.0.0-beta.4",
"date-fns": "2.30.0",
@ -57,7 +57,7 @@
"photoswipe": "5.4.2",
"punycode": "2.3.1",
"querystring": "0.2.1",
"rollup": "4.2.0",
"rollup": "4.4.0",
"sanitize-html": "2.11.0",
"shiki": "^0.14.5",
"sass": "1.69.5",
@ -74,62 +74,62 @@
"v-code-diff": "1.7.2",
"vanilla-tilt": "1.8.1",
"vite": "4.5.0",
"vue": "3.3.7",
"vue": "3.3.8",
"vuedraggable": "next"
},
"devDependencies": {
"@storybook/addon-actions": "7.5.2",
"@storybook/addon-essentials": "7.5.2",
"@storybook/addon-interactions": "7.5.2",
"@storybook/addon-links": "7.5.2",
"@storybook/addon-storysource": "7.5.2",
"@storybook/addons": "7.5.2",
"@storybook/blocks": "7.5.2",
"@storybook/core-events": "7.5.2",
"@storybook/addon-actions": "7.5.3",
"@storybook/addon-essentials": "7.5.3",
"@storybook/addon-interactions": "7.5.3",
"@storybook/addon-links": "7.5.3",
"@storybook/addon-storysource": "7.5.3",
"@storybook/addons": "7.5.3",
"@storybook/blocks": "7.5.3",
"@storybook/core-events": "7.5.3",
"@storybook/jest": "0.2.3",
"@storybook/manager-api": "7.5.2",
"@storybook/preview-api": "7.5.2",
"@storybook/react": "7.5.2",
"@storybook/react-vite": "7.5.2",
"@storybook/manager-api": "7.5.3",
"@storybook/preview-api": "7.5.3",
"@storybook/react": "7.5.3",
"@storybook/react-vite": "7.5.3",
"@storybook/testing-library": "0.2.2",
"@storybook/theming": "7.5.2",
"@storybook/types": "7.5.2",
"@storybook/vue3": "7.5.2",
"@storybook/vue3-vite": "7.5.2",
"@storybook/theming": "7.5.3",
"@storybook/types": "7.5.3",
"@storybook/vue3": "7.5.3",
"@storybook/vue3-vite": "7.5.3",
"@testing-library/vue": "8.0.0",
"@types/escape-regexp": "0.0.2",
"@types/estree": "1.0.4",
"@types/matter-js": "0.19.2",
"@types/micromatch": "4.0.4",
"@types/node": "20.8.10",
"@types/punycode": "2.1.1",
"@types/sanitize-html": "2.9.3",
"@types/throttle-debounce": "5.0.1",
"@types/tinycolor2": "1.4.5",
"@types/uuid": "9.0.6",
"@types/websocket": "1.0.8",
"@types/ws": "8.5.8",
"@typescript-eslint/eslint-plugin": "6.9.1",
"@typescript-eslint/parser": "6.9.1",
"@types/escape-regexp": "0.0.3",
"@types/estree": "1.0.5",
"@types/matter-js": "0.19.4",
"@types/micromatch": "4.0.5",
"@types/node": "20.9.0",
"@types/punycode": "2.1.2",
"@types/sanitize-html": "2.9.4",
"@types/throttle-debounce": "5.0.2",
"@types/tinycolor2": "1.4.6",
"@types/uuid": "9.0.7",
"@types/websocket": "1.0.9",
"@types/ws": "8.5.9",
"@typescript-eslint/eslint-plugin": "6.11.0",
"@typescript-eslint/parser": "6.11.0",
"@vitest/coverage-v8": "0.34.6",
"@vue/runtime-core": "3.3.7",
"@vue/runtime-core": "3.3.8",
"acorn": "8.11.2",
"cross-env": "7.0.3",
"cypress": "13.4.0",
"eslint": "8.52.0",
"cypress": "13.5.0",
"eslint": "8.53.0",
"eslint-plugin-import": "2.29.0",
"eslint-plugin-vue": "9.18.1",
"fast-glob": "3.3.1",
"fast-glob": "3.3.2",
"happy-dom": "10.0.3",
"micromatch": "4.0.5",
"msw": "1.3.2",
"msw-storybook-addon": "1.10.0",
"nodemon": "3.0.1",
"prettier": "3.0.3",
"prettier": "3.1.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"start-server-and-test": "2.0.1",
"storybook": "7.5.2",
"start-server-and-test": "2.0.2",
"storybook": "7.5.3",
"storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme",
"summaly": "github:misskey-dev/summaly",
"vite-plugin-turbosnap": "1.0.3",

View File

@ -20,13 +20,13 @@
"url": "git+https://github.com/misskey-dev/misskey.js.git"
},
"devDependencies": {
"@microsoft/api-extractor": "7.38.2",
"@microsoft/api-extractor": "7.38.3",
"@swc/jest": "0.2.29",
"@types/jest": "29.5.7",
"@types/node": "20.8.10",
"@typescript-eslint/eslint-plugin": "6.9.1",
"@typescript-eslint/parser": "6.9.1",
"eslint": "8.52.0",
"@types/jest": "29.5.8",
"@types/node": "20.9.0",
"@typescript-eslint/eslint-plugin": "6.11.0",
"@typescript-eslint/parser": "6.11.0",
"eslint": "8.53.0",
"jest": "29.7.0",
"jest-fetch-mock": "3.0.3",
"jest-websocket-mock": "2.5.0",
@ -39,7 +39,7 @@
],
"dependencies": {
"@swc/cli": "0.1.62",
"@swc/core": "1.3.95",
"@swc/core": "1.3.96",
"eventemitter3": "5.0.1",
"reconnecting-websocket": "4.4.0"
}

View File

@ -14,9 +14,9 @@
"misskey-js": "workspace:*"
},
"devDependencies": {
"@typescript-eslint/parser": "6.9.1",
"@typescript-eslint/parser": "6.11.0",
"@typescript/lib-webworker": "npm:@types/serviceworker@0.0.67",
"eslint": "8.52.0",
"eslint": "8.53.0",
"eslint-plugin-import": "2.29.0",
"typescript": "5.2.2"
},

File diff suppressed because it is too large Load Diff