From 245ceb14fa2134a0dac80af7fbb1d6a1df3ece8a Mon Sep 17 00:00:00 2001 From: Danielv123 Date: Sat, 21 Feb 2026 16:25:11 +0100 Subject: [PATCH] security(minimap): fix path traversal in controller file loading --- plugins/minimap/controller.ts | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/plugins/minimap/controller.ts b/plugins/minimap/controller.ts index 36b72c68..8fd7cd41 100644 --- a/plugins/minimap/controller.ts +++ b/plugins/minimap/controller.ts @@ -839,7 +839,11 @@ export class ControllerPlugin extends BaseControllerPlugin { private async loadTagContentFromFile(file: string) { const fileKey = file.replace("_chart_tags.json", ""); - const filePath = path.join(this.chartTagsPath, file); + const filePath = resolveFileInDir(this.chartTagsPath, file); + if (filePath === null) { + this.logger.warn(`Invalid chart tag file path: ${file}`); + return; + } if (!this.lastSeenTagContent.has(fileKey)) { this.lastSeenTagContent.set(fileKey, new Map()); @@ -897,7 +901,11 @@ export class ControllerPlugin extends BaseControllerPlugin { for (const file of recipeFiles) { const tileKey = file.replace(".recipes", ""); - const filePath = path.join(this.recipeTilesPath, file); + const filePath = resolveFileInDir(this.recipeTilesPath, file); + if (filePath === null) { + this.logger.warn(`Invalid recipe file path: ${file}`); + continue; + } // Initialise structures this.lastSeenRecipeContent.set(tileKey, new Map()); @@ -1672,7 +1680,11 @@ export class ControllerPlugin extends BaseControllerPlugin { for (const file of positionFiles) { const fileKey = file.replace(".positions", ""); - const filePath = path.join(this.playerPositionsPath, file); + const filePath = resolveFileInDir(this.playerPositionsPath, file); + if (filePath === null) { + this.logger.warn(`Invalid player positions file path: ${file}`); + continue; + } if (!this.playerSessions.has(fileKey)) { this.playerSessions.set(fileKey, new Map());