try to honour user blocks on AP requests - #248

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 ☹
This commit is contained in:
dakkar 2024-03-03 14:54:36 +00:00
parent 2e55108b6b
commit 606531a4b3

View file

@ -31,6 +31,7 @@ import type { MiNote } from '@/models/Note.js';
import { QueryService } from '@/core/QueryService.js'; import { QueryService } from '@/core/QueryService.js';
import { UtilityService } from '@/core/UtilityService.js'; import { UtilityService } from '@/core/UtilityService.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { UserBlockingService } from '@/core/UserBlockingService.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { IActivity } from '@/core/activitypub/type.js'; import { IActivity } from '@/core/activitypub/type.js';
import { isPureRenote } from '@/misc/is-pure-renote.js'; import { isPureRenote } from '@/misc/is-pure-renote.js';
@ -78,6 +79,7 @@ export class ActivityPubServerService {
private metaService: MetaService, private metaService: MetaService,
private utilityService: UtilityService, private utilityService: UtilityService,
private userEntityService: UserEntityService, private userEntityService: UserEntityService,
private userBlockingService: UserBlockingService,
private instanceActorService: InstanceActorService, private instanceActorService: InstanceActorService,
private apRendererService: ApRendererService, private apRendererService: ApRendererService,
private apDbResolverService: ApDbResolverService, private apDbResolverService: ApDbResolverService,
@ -206,6 +208,17 @@ export class ActivityPubServerService {
return true; 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); let httpSignatureValidated = httpSignature.verifySignature(signature, authUser.key.keyPem);
if (!httpSignatureValidated) { if (!httpSignatureValidated) {
@ -706,6 +719,8 @@ export class ActivityPubServerService {
return; return;
} }
if (await this.shouldRefuseGetRequest(request, reply, note.userId)) return;
// リモートだったらリダイレクト // リモートだったらリダイレクト
if (note.userHost != null) { if (note.userHost != null) {
if (note.uri == null || this.utilityService.isSelfHost(note.userHost)) { if (note.uri == null || this.utilityService.isSelfHost(note.userHost)) {
@ -739,6 +754,8 @@ export class ActivityPubServerService {
return; return;
} }
if (await this.shouldRefuseGetRequest(request, reply, note.userId)) return;
if (!this.config.checkActivityPubGetSignature) reply.header('Cache-Control', 'public, max-age=180'); if (!this.config.checkActivityPubGetSignature) reply.header('Cache-Control', 'public, max-age=180');
this.setResponseType(request, reply); this.setResponseType(request, reply);
return (this.apRendererService.addContext(await this.packActivity(note))); return (this.apRendererService.addContext(await this.packActivity(note)));
@ -861,6 +878,8 @@ export class ActivityPubServerService {
return; return;
} }
if (await this.shouldRefuseGetRequest(request, reply, note.userId)) return;
if (!this.config.checkActivityPubGetSignature) reply.header('Cache-Control', 'public, max-age=180'); if (!this.config.checkActivityPubGetSignature) reply.header('Cache-Control', 'public, max-age=180');
this.setResponseType(request, reply); this.setResponseType(request, reply);
return (this.apRendererService.addContext(await this.apRendererService.renderLike(reaction, note))); return (this.apRendererService.addContext(await this.apRendererService.renderLike(reaction, note)));
@ -868,7 +887,7 @@ export class ActivityPubServerService {
// follow // follow
fastify.get<{ Params: { follower: string; followee: string; } }>('/follows/:follower/:followee', async (request, reply) => { 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 // This may be used before the follow is completed, so we do not
// check if the following exists. // check if the following exists.
@ -910,6 +929,8 @@ export class ActivityPubServerService {
return; return;
} }
if (await this.shouldRefuseGetRequest(request, reply, followRequest.followerId)) return;
const [follower, followee] = await Promise.all([ const [follower, followee] = await Promise.all([
this.usersRepository.findOneBy({ this.usersRepository.findOneBy({
id: followRequest.followerId, id: followRequest.followerId,