From 606531a4b37be81171e3d36193b7459bf24a67ae Mon Sep 17 00:00:00 2001 From: dakkar Date: Sun, 3 Mar 2024 14:54:36 +0000 Subject: [PATCH] try to honour user blocks on AP requests - #248 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit as the comment says, this doesn't really work, because requests can be signed by the remote instance actor instead of the real remote user e.g. Misskey (and us) seems to always sign as the instance actor when fetching notes ☹ --- .../src/server/ActivityPubServerService.ts | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/packages/backend/src/server/ActivityPubServerService.ts b/packages/backend/src/server/ActivityPubServerService.ts index 64bce07a98..43e0e2f328 100644 --- a/packages/backend/src/server/ActivityPubServerService.ts +++ b/packages/backend/src/server/ActivityPubServerService.ts @@ -31,6 +31,7 @@ import type { MiNote } from '@/models/Note.js'; import { QueryService } from '@/core/QueryService.js'; import { UtilityService } from '@/core/UtilityService.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; +import { UserBlockingService } from '@/core/UserBlockingService.js'; import { bindThis } from '@/decorators.js'; import { IActivity } from '@/core/activitypub/type.js'; import { isPureRenote } from '@/misc/is-pure-renote.js'; @@ -78,6 +79,7 @@ export class ActivityPubServerService { private metaService: MetaService, private utilityService: UtilityService, private userEntityService: UserEntityService, + private userBlockingService: UserBlockingService, private instanceActorService: InstanceActorService, private apRendererService: ApRendererService, private apDbResolverService: ApDbResolverService, @@ -206,6 +208,17 @@ export class ActivityPubServerService { return true; } + if (userId) { + /* this check is not really effective, because most requests we + get are signed by the remote instance user, not the user + who's requesting the information 😭 */ + const blocked = await this.userBlockingService.checkBlocked(userId, authUser.user.id); + if (blocked) { + reply.code(401); + return true; + } + } + let httpSignatureValidated = httpSignature.verifySignature(signature, authUser.key.keyPem); if (!httpSignatureValidated) { @@ -706,6 +719,8 @@ export class ActivityPubServerService { return; } + if (await this.shouldRefuseGetRequest(request, reply, note.userId)) return; + // γƒͺγƒ’γƒΌγƒˆγ γ£γŸγ‚‰γƒͺγƒ€γ‚€γƒ¬γ‚―γƒˆ if (note.userHost != null) { if (note.uri == null || this.utilityService.isSelfHost(note.userHost)) { @@ -739,6 +754,8 @@ export class ActivityPubServerService { return; } + if (await this.shouldRefuseGetRequest(request, reply, note.userId)) return; + if (!this.config.checkActivityPubGetSignature) reply.header('Cache-Control', 'public, max-age=180'); this.setResponseType(request, reply); return (this.apRendererService.addContext(await this.packActivity(note))); @@ -861,6 +878,8 @@ export class ActivityPubServerService { return; } + if (await this.shouldRefuseGetRequest(request, reply, note.userId)) return; + if (!this.config.checkActivityPubGetSignature) reply.header('Cache-Control', 'public, max-age=180'); this.setResponseType(request, reply); return (this.apRendererService.addContext(await this.apRendererService.renderLike(reaction, note))); @@ -868,7 +887,7 @@ export class ActivityPubServerService { // follow fastify.get<{ Params: { follower: string; followee: string; } }>('/follows/:follower/:followee', async (request, reply) => { - if (await this.shouldRefuseGetRequest(request, reply)) return; + if (await this.shouldRefuseGetRequest(request, reply, request.params.follwer)) return; // This may be used before the follow is completed, so we do not // check if the following exists. @@ -910,6 +929,8 @@ export class ActivityPubServerService { return; } + if (await this.shouldRefuseGetRequest(request, reply, followRequest.followerId)) return; + const [follower, followee] = await Promise.all([ this.usersRepository.findOneBy({ id: followRequest.followerId,