From 0d7256678e390af9e7576571b3fd262e265fbe18 Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Sun, 5 Feb 2023 14:25:37 +0900
Subject: [PATCH] fix(server): validate filename and emoji name to improve
 security

---
 .../queue/processors/ExportCustomEmojisProcessorService.ts  | 6 +++++-
 .../queue/processors/ImportCustomEmojisProcessorService.ts  | 4 ++++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/packages/backend/src/queue/processors/ExportCustomEmojisProcessorService.ts b/packages/backend/src/queue/processors/ExportCustomEmojisProcessorService.ts
index 87b23f1891..df024a8f3c 100644
--- a/packages/backend/src/queue/processors/ExportCustomEmojisProcessorService.ts
+++ b/packages/backend/src/queue/processors/ExportCustomEmojisProcessorService.ts
@@ -12,9 +12,9 @@ import type Logger from '@/logger.js';
 import { DriveService } from '@/core/DriveService.js';
 import { createTemp, createTempDir } from '@/misc/create-temp.js';
 import { DownloadService } from '@/core/DownloadService.js';
+import { bindThis } from '@/decorators.js';
 import { QueueLoggerService } from '../QueueLoggerService.js';
 import type Bull from 'bull';
-import { bindThis } from '@/decorators.js';
 
 @Injectable()
 export class ExportCustomEmojisProcessorService {
@@ -82,6 +82,10 @@ export class ExportCustomEmojisProcessorService {
 		});
 
 		for (const emoji of customEmojis) {
+			if (!/^[a-zA-Z0-9_]+$/.test(emoji.name)) {
+				this.logger.error(`invalid emoji name: ${emoji.name}`);
+				continue;
+			}
 			const ext = mime.extension(emoji.type ?? 'image/png');
 			const fileName = emoji.name + (ext ? '.' + ext : '');
 			const emojiPath = path + '/' + fileName;
diff --git a/packages/backend/src/queue/processors/ImportCustomEmojisProcessorService.ts b/packages/backend/src/queue/processors/ImportCustomEmojisProcessorService.ts
index 0061c2a8f7..2d43615e25 100644
--- a/packages/backend/src/queue/processors/ImportCustomEmojisProcessorService.ts
+++ b/packages/backend/src/queue/processors/ImportCustomEmojisProcessorService.ts
@@ -81,6 +81,10 @@ export class ImportCustomEmojisProcessorService {
 
 			for (const record of meta.emojis) {
 				if (!record.downloaded) continue;
+				if (!/^[a-zA-Z0-9_]+?([a-zA-Z0-9\.]+)?$/.test(record.fileName)) {
+					this.logger.error(`invalid filename: ${record.fileName}`);
+					continue;
+				}
 				const emojiInfo = record.emoji;
 				const emojiPath = outputPath + '/' + record.fileName;
 				await this.emojisRepository.delete({