From 58a3a0b7d42e7a91d332e11715f45e36c0a7bd56 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 3 Dec 2022 18:42:06 +0900 Subject: [PATCH 001/113] forkbomb DOS mitigation --- .../src/remote/activitypub/kernel/update/index.ts | 8 ++++---- .../src/remote/activitypub/models/person.ts | 8 ++++---- .../src/remote/activitypub/models/question.ts | 8 ++++---- .../backend/src/remote/activitypub/resolver.ts | 15 ++++++++++----- 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/packages/backend/src/remote/activitypub/kernel/update/index.ts b/packages/backend/src/remote/activitypub/kernel/update/index.ts index 9e8a81bb3..a142cb46e 100644 --- a/packages/backend/src/remote/activitypub/kernel/update/index.ts +++ b/packages/backend/src/remote/activitypub/kernel/update/index.ts @@ -10,7 +10,7 @@ import { updatePerson } from '../../models/person.js'; */ export default async (actor: CacheableRemoteUser, activity: IUpdate): Promise => { if ('actor' in activity && actor.uri !== activity.actor) { - return `skip: invalid actor`; + return 'skip: invalid actor'; } apLogger.debug('Update'); @@ -24,10 +24,10 @@ export default async (actor: CacheableRemoteUser, activity: IUpdate): Promise console.log(e)); - return `ok: Question updated`; + await updateQuestion(object, resolver).catch(e => console.log(e)); + return 'ok: Question updated'; } else { return `skip: Unknown type: ${getApType(object)}`; } diff --git a/packages/backend/src/remote/activitypub/models/person.ts b/packages/backend/src/remote/activitypub/models/person.ts index 6097e3b6e..5ef04588e 100644 --- a/packages/backend/src/remote/activitypub/models/person.ts +++ b/packages/backend/src/remote/activitypub/models/person.ts @@ -271,7 +271,7 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise logger.error(err)); + await updateFeatured(user!.id, resolver).catch(err => logger.error(err)); return user!; } @@ -384,7 +384,7 @@ export async function updatePerson(uri: string, resolver?: Resolver | null, hint followerSharedInbox: person.sharedInbox || (person.endpoints ? person.endpoints.sharedInbox : undefined), }); - await updateFeatured(exist.id).catch(err => logger.error(err)); + await updateFeatured(exist.id, resolver).catch(err => logger.error(err)); } /** @@ -462,14 +462,14 @@ export function analyzeAttachments(attachments: IObject | IObject[] | undefined) return { fields, services }; } -export async function updateFeatured(userId: User['id']) { +export async function updateFeatured(userId: User['id'], resolver?: Resolver) { const user = await Users.findOneByOrFail({ id: userId }); if (!Users.isRemoteUser(user)) return; if (!user.featured) return; logger.info(`Updating the featured: ${user.uri}`); - const resolver = new Resolver(); + if (resolver == null) resolver = new Resolver(); // Resolve to (Ordered)Collection Object const collection = await resolver.resolveCollection(user.featured); diff --git a/packages/backend/src/remote/activitypub/models/question.ts b/packages/backend/src/remote/activitypub/models/question.ts index f0321fdf2..57070fb1e 100644 --- a/packages/backend/src/remote/activitypub/models/question.ts +++ b/packages/backend/src/remote/activitypub/models/question.ts @@ -1,9 +1,9 @@ import config from '@/config/index.js'; +import { Notes, Polls } from '@/models/index.js'; +import { IPoll } from '@/models/entities/poll.js'; import Resolver from '../resolver.js'; import { IObject, IQuestion, isQuestion } from '../type.js'; import { apLogger } from '../logger.js'; -import { Notes, Polls } from '@/models/index.js'; -import { IPoll } from '@/models/entities/poll.js'; export async function extractPollFromQuestion(source: string | IObject, resolver?: Resolver): Promise { if (resolver == null) resolver = new Resolver(); @@ -40,7 +40,7 @@ export async function extractPollFromQuestion(source: string | IObject, resolver * @param uri URI of AP Question object * @returns true if updated */ -export async function updateQuestion(value: any) { +export async function updateQuestion(value: any, resolver?: Resolver) { const uri = typeof value === 'string' ? value : value.id; // URIがこのサーバーを指しているならスキップ @@ -55,7 +55,7 @@ export async function updateQuestion(value: any) { //#endregion // resolve new Question object - const resolver = new Resolver(); + if (resolver == null) resolver = new Resolver(); const question = await resolver.resolve(value) as IQuestion; apLogger.debug(`fetched question: ${JSON.stringify(question, null, 2)}`); diff --git a/packages/backend/src/remote/activitypub/resolver.ts b/packages/backend/src/remote/activitypub/resolver.ts index 2f9af43c0..ad0df0c97 100644 --- a/packages/backend/src/remote/activitypub/resolver.ts +++ b/packages/backend/src/remote/activitypub/resolver.ts @@ -4,10 +4,7 @@ import { ILocalUser } from '@/models/entities/user.js'; import { getInstanceActor } from '@/services/instance-actor.js'; import { fetchMeta } from '@/misc/fetch-meta.js'; import { extractDbHost, isSelfHost } from '@/misc/convert-host.js'; -import { signedGet } from './request.js'; -import { IObject, isCollectionOrOrderedCollection, ICollection, IOrderedCollection } from './type.js'; import { FollowRequests, Notes, NoteReactions, Polls, Users } from '@/models/index.js'; -import { parseUri } from './db-resolver.js'; import renderNote from '@/remote/activitypub/renderer/note.js'; import { renderLike } from '@/remote/activitypub/renderer/like.js'; import { renderPerson } from '@/remote/activitypub/renderer/person.js'; @@ -15,12 +12,16 @@ import renderQuestion from '@/remote/activitypub/renderer/question.js'; import renderCreate from '@/remote/activitypub/renderer/create.js'; import { renderActivity } from '@/remote/activitypub/renderer/index.js'; import renderFollow from '@/remote/activitypub/renderer/follow.js'; +import { parseUri } from './db-resolver.js'; +import { IObject, isCollectionOrOrderedCollection, ICollection, IOrderedCollection } from './type.js'; +import { signedGet } from './request.js'; export default class Resolver { private history: Set; private user?: ILocalUser; + private recursionLimit?: number; - constructor() { + constructor(recursionLimit = 100) { this.history = new Set(); } @@ -60,6 +61,10 @@ export default class Resolver { throw new Error('cannot resolve already resolved one'); } + if (this.recursionLimit && this.history.size > this.recursionLimit) { + throw new Error('hit recursion limit'); + } + this.history.add(value); const host = extractDbHost(value); @@ -123,7 +128,7 @@ export default class Resolver { if (parsed.rest == null || !/^\w+$/.test(parsed.rest)) throw new Error('resolveLocal: invalid follow URI'); return Promise.all( - [parsed.id, parsed.rest].map(id => Users.findOneByOrFail({ id })) + [parsed.id, parsed.rest].map(id => Users.findOneByOrFail({ id })), ) .then(([follower, followee]) => renderActivity(renderFollow(follower, followee, url))); default: From fccd9c32e8c2dc0fd4628b42770417d7fc35776b Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 3 Dec 2022 18:42:19 +0900 Subject: [PATCH 002/113] 12.119.1 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5bafc0a01..3ecc8ef1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ You should also include the user name that made the change. --> +## 12.119.1 (2022/12/03) +### Bugfixes +- Server: Mitigate AP reference chain DoS vector @skehmatics + ## 12.119.0 (2022/09/10) ### Improvements diff --git a/package.json b/package.json index 37f0762f5..5a190d79b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "misskey", - "version": "12.119.0", + "version": "12.119.1", "codename": "indigo", "repository": { "type": "git", From fcabc993038b81b310bc3752ac756a406679013a Mon Sep 17 00:00:00 2001 From: rinsuki <428rinsuki+git@gmail.com> Date: Sun, 4 Dec 2022 05:34:51 +0900 Subject: [PATCH 003/113] =?UTF-8?q?master=E3=83=96=E3=83=A9=E3=83=B3?= =?UTF-8?q?=E3=83=81=E3=82=92master=5Fsecurity=E3=81=A8=E3=83=9E=E3=83=BC?= =?UTF-8?q?=E3=82=B8=20(#9260)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix: forkbomb 2 * 12.119.2 Co-authored-by: mei23 --- CHANGELOG.md | 4 ++++ package.json | 2 +- packages/backend/src/remote/activitypub/models/mention.ts | 4 +--- packages/backend/src/remote/activitypub/models/note.ts | 4 ++-- packages/backend/src/remote/activitypub/resolver.ts | 1 + 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ecc8ef1f..d97e34b77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ You should also include the user name that made the change. --> +## 12.119.2 (2022/12/04) +### Bugfixes +- Server: Backported versions mitigate isn't working @mei23 + ## 12.119.1 (2022/12/03) ### Bugfixes - Server: Mitigate AP reference chain DoS vector @skehmatics diff --git a/package.json b/package.json index 5a190d79b..a23a075d7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "misskey", - "version": "12.119.1", + "version": "12.119.2", "codename": "indigo", "repository": { "type": "git", diff --git a/packages/backend/src/remote/activitypub/models/mention.ts b/packages/backend/src/remote/activitypub/models/mention.ts index 13f77424e..7483992d2 100644 --- a/packages/backend/src/remote/activitypub/models/mention.ts +++ b/packages/backend/src/remote/activitypub/models/mention.ts @@ -5,11 +5,9 @@ import { IObject, isMention, IApMention } from '../type.js'; import Resolver from '../resolver.js'; import { resolvePerson } from './person.js'; -export async function extractApMentions(tags: IObject | IObject[] | null | undefined) { +export async function extractApMentions(tags: IObject | IObject[] | null | undefined, resolver: Resolver) { const hrefs = unique(extractApMentionObjects(tags).map(x => x.href as string)); - const resolver = new Resolver(); - const limit = promiseLimit(2); const mentionedUsers = (await Promise.all( hrefs.map(x => limit(() => resolvePerson(x, resolver).catch(() => null))), diff --git a/packages/backend/src/remote/activitypub/models/note.ts b/packages/backend/src/remote/activitypub/models/note.ts index 5d63f2605..8aca589c9 100644 --- a/packages/backend/src/remote/activitypub/models/note.ts +++ b/packages/backend/src/remote/activitypub/models/note.ts @@ -97,7 +97,7 @@ export async function createNote(value: string | IObject, resolver?: Resolver, s throw new Error('actor has been suspended'); } - const noteAudience = await parseAudience(actor, note.to, note.cc); + const noteAudience = await parseAudience(actor, note.to, note.cc, resolver); let visibility = noteAudience.visibility; const visibleUsers = noteAudience.visibleUsers; @@ -111,7 +111,7 @@ export async function createNote(value: string | IObject, resolver?: Resolver, s let isTalk = note._misskey_talk && visibility === 'specified'; - const apMentions = await extractApMentions(note.tag); + const apMentions = await extractApMentions(note.tag, resolver); const apHashtags = await extractApHashtags(note.tag); // 添付ファイル diff --git a/packages/backend/src/remote/activitypub/resolver.ts b/packages/backend/src/remote/activitypub/resolver.ts index ad0df0c97..6514c0660 100644 --- a/packages/backend/src/remote/activitypub/resolver.ts +++ b/packages/backend/src/remote/activitypub/resolver.ts @@ -23,6 +23,7 @@ export default class Resolver { constructor(recursionLimit = 100) { this.history = new Set(); + this.recursionLimit = recursionLimit; } public getHistory(): string[] { From 039a2af3ab37aadccb80cc8a082837b3579c162e Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 22 Jan 2023 17:18:39 +0900 Subject: [PATCH 004/113] tweak boot.js --- packages/backend/src/server/web/boot.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/server/web/boot.js b/packages/backend/src/server/web/boot.js index 3d6dabe57..e635959fc 100644 --- a/packages/backend/src/server/web/boot.js +++ b/packages/backend/src/server/web/boot.js @@ -55,7 +55,7 @@ renderError('META_FETCH'); return; } - const meta = await res.json(); + const meta = await metaRes.json(); const v = meta.version; if (v == null) { renderError('META_FETCH_V'); From 0c59dd3da7c4fd065bfb46f1849f8b011959e1c4 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 19 Feb 2023 17:49:55 +0900 Subject: [PATCH 005/113] Update about-misskey.vue --- packages/frontend/src/pages/about-misskey.vue | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/frontend/src/pages/about-misskey.vue b/packages/frontend/src/pages/about-misskey.vue index bc3d24819..b5f38d1c6 100644 --- a/packages/frontend/src/pages/about-misskey.vue +++ b/packages/frontend/src/pages/about-misskey.vue @@ -111,6 +111,9 @@ const patronsWithIcon = [{ }, { name: 'だれかさん', icon: 'https://misskey-hub.net/patrons/f7409b5e5a88477a9b9d740c408de125.jpg', +}, { + name: 'narazaka', + icon: 'https://misskey-hub.net/patrons/e3affff31ffb4877b1196c7360abc3e5.jpg', }]; const patrons = [ From 7ce0f79f7fd77f1417ab597bfac8b80f2c6bbcde Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 19 Feb 2023 17:50:14 +0900 Subject: [PATCH 006/113] chore(server): tweak notes/featured api --- packages/backend/src/server/api/endpoints/notes/featured.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/server/api/endpoints/notes/featured.ts b/packages/backend/src/server/api/endpoints/notes/featured.ts index 8eff8fdb2..26f69373d 100644 --- a/packages/backend/src/server/api/endpoints/notes/featured.ts +++ b/packages/backend/src/server/api/endpoints/notes/featured.ts @@ -68,7 +68,7 @@ export default class extends Endpoint { let notes = await query .orderBy('note.score', 'DESC') - .take(ps.limit) + .take(50) .getMany(); notes.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()); From 47b6f466ec0031478a246a02e8dd2bab156fb0da Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 19 Feb 2023 19:54:19 +0900 Subject: [PATCH 007/113] enhance(client): snap scroll on deck --- packages/frontend/src/ui/deck.vue | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/frontend/src/ui/deck.vue b/packages/frontend/src/ui/deck.vue index ef29b2e72..4e9335959 100644 --- a/packages/frontend/src/ui/deck.vue +++ b/packages/frontend/src/ui/deck.vue @@ -4,7 +4,7 @@
-
+