From c48faca707ca50c3f5ea05a4a6e1359b9fc7dcf6 Mon Sep 17 00:00:00 2001
From: Hazelnoot <acomputerdog@gmail.com>
Date: Mon, 18 Nov 2024 10:33:32 -0500
Subject: [PATCH 1/3] fix lint errors in UrlPreviewService

---
 packages/backend/src/server/web/UrlPreviewService.ts | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/packages/backend/src/server/web/UrlPreviewService.ts b/packages/backend/src/server/web/UrlPreviewService.ts
index 47cc09b067..adb188b66f 100644
--- a/packages/backend/src/server/web/UrlPreviewService.ts
+++ b/packages/backend/src/server/web/UrlPreviewService.ts
@@ -6,6 +6,7 @@
 import { Inject, Injectable } from '@nestjs/common';
 import { summaly } from '@misskey-dev/summaly';
 import { SummalyResult } from '@misskey-dev/summaly/built/summary.js';
+import * as Redis from 'ioredis';
 import { DI } from '@/di-symbols.js';
 import type { Config } from '@/config.js';
 import { HttpRequestService } from '@/core/HttpRequestService.js';
@@ -15,9 +16,8 @@ import { LoggerService } from '@/core/LoggerService.js';
 import { bindThis } from '@/decorators.js';
 import { ApiError } from '@/server/api/error.js';
 import { MiMeta } from '@/models/Meta.js';
-import type { FastifyRequest, FastifyReply } from 'fastify';
-import * as Redis from 'ioredis';
 import { RedisKVCache } from '@/misc/cache.js';
+import type { FastifyRequest, FastifyReply } from 'fastify';
 
 @Injectable()
 export class UrlPreviewService {
@@ -41,7 +41,7 @@ export class UrlPreviewService {
 		this.previewCache = new RedisKVCache<SummalyResult>(this.redisClient, 'summaly', {
 			lifetime: 1000 * 60 * 60 * 24, // 1d
 			memoryCacheLifetime: 1000 * 60 * 10, // 10m
-			fetcher: (key: string) => { throw new Error('the UrlPreview cache should never fetch'); },
+			fetcher: () => { throw new Error('the UrlPreview cache should never fetch'); },
 			toRedisConverter: (value) => JSON.stringify(value),
 			fromRedisConverter: (value) => JSON.parse(value),
 		});
-- 
GitLab


From 4c6cec552eb629f6c796bbc42db319e218f89515 Mon Sep 17 00:00:00 2001
From: Hazelnoot <acomputerdog@gmail.com>
Date: Mon, 18 Nov 2024 10:41:18 -0500
Subject: [PATCH 2/3] verify that preview URL is valid

---
 packages/backend/src/server/web/UrlPreviewService.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/backend/src/server/web/UrlPreviewService.ts b/packages/backend/src/server/web/UrlPreviewService.ts
index adb188b66f..26ea185586 100644
--- a/packages/backend/src/server/web/UrlPreviewService.ts
+++ b/packages/backend/src/server/web/UrlPreviewService.ts
@@ -65,7 +65,7 @@ export class UrlPreviewService {
 		reply: FastifyReply,
 	): Promise<object | undefined> {
 		const url = request.query.url;
-		if (typeof url !== 'string') {
+		if (typeof url !== 'string' || !URL.canParse(url)) {
 			reply.code(400);
 			return;
 		}
-- 
GitLab


From 2a4c432f41580cf2afa97bfd1a35153883b318db Mon Sep 17 00:00:00 2001
From: Hazelnoot <acomputerdog@gmail.com>
Date: Mon, 18 Nov 2024 10:41:31 -0500
Subject: [PATCH 3/3] don't generate URL previews for blocked domains

---
 .../backend/src/server/web/UrlPreviewService.ts    | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/packages/backend/src/server/web/UrlPreviewService.ts b/packages/backend/src/server/web/UrlPreviewService.ts
index 26ea185586..19dac1dfb8 100644
--- a/packages/backend/src/server/web/UrlPreviewService.ts
+++ b/packages/backend/src/server/web/UrlPreviewService.ts
@@ -17,6 +17,7 @@ import { bindThis } from '@/decorators.js';
 import { ApiError } from '@/server/api/error.js';
 import { MiMeta } from '@/models/Meta.js';
 import { RedisKVCache } from '@/misc/cache.js';
+import { UtilityService } from '@/core/UtilityService.js';
 import type { FastifyRequest, FastifyReply } from 'fastify';
 
 @Injectable()
@@ -36,6 +37,7 @@ export class UrlPreviewService {
 
 		private httpRequestService: HttpRequestService,
 		private loggerService: LoggerService,
+		private utilityService: UtilityService,
 	) {
 		this.logger = this.loggerService.getLogger('url-preview');
 		this.previewCache = new RedisKVCache<SummalyResult>(this.redisClient, 'summaly', {
@@ -87,6 +89,18 @@ export class UrlPreviewService {
 			};
 		}
 
+		const host = new URL(url).host;
+		if (this.utilityService.isBlockedHost(this.meta.blockedHosts, host)) {
+			reply.code(403);
+			return {
+				error: new ApiError({
+					message: 'URL is blocked',
+					code: 'URL_PREVIEW_BLOCKED',
+					id: '50294652-857b-4b13-9700-8e5c7a8deae8',
+				}),
+			};
+		}
+
 		const key = `${url}@${lang}`;
 		const cached = await this.previewCache.get(key);
 		if (cached !== undefined) {
-- 
GitLab