From 3c88aec034934bcbad30c5ef1cab62cbbdb98e64 Mon Sep 17 00:00:00 2001 From: Timothy Carambat <rambat1010@gmail.com> Date: Mon, 11 Sep 2023 22:07:48 +0200 Subject: [PATCH] prevent exports path traversal (#233) --- .../Modals/MangeWorkspace/Documents/index.jsx | 5 +-- server/endpoints/system.js | 31 +++++++++++++------ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/frontend/src/components/Modals/MangeWorkspace/Documents/index.jsx b/frontend/src/components/Modals/MangeWorkspace/Documents/index.jsx index 3dcfd3374..628f22c51 100644 --- a/frontend/src/components/Modals/MangeWorkspace/Documents/index.jsx +++ b/frontend/src/components/Modals/MangeWorkspace/Documents/index.jsx @@ -177,8 +177,9 @@ export default function DocumentSettings({ workspace }) { </div> </div> <div - className={`flex items-center ${canDelete ? "justify-between" : "justify-end" - } p-4 md:p-6 space-x-2 border-t border-gray-200 rounded-b dark:border-gray-600`} + className={`flex items-center ${ + canDelete ? "justify-between" : "justify-end" + } p-4 md:p-6 space-x-2 border-t border-gray-200 rounded-b dark:border-gray-600`} > <button hidden={!canDelete} diff --git a/server/endpoints/system.js b/server/endpoints/system.js index 736ab1418..d493a2c2a 100644 --- a/server/endpoints/system.js +++ b/server/endpoints/system.js @@ -24,6 +24,7 @@ const { User } = require("../models/user"); const { validatedRequest } = require("../utils/middleware/validatedRequest"); const { handleImports } = setupDataImports(); const { handleLogoUploads } = setupLogoUploads(); +const fs = require("fs"); const path = require("path"); const { getDefaultFilename, @@ -315,9 +316,21 @@ function systemEndpoints(app) { "/system/data-exports/:filename", [validatedRequest], (request, response) => { - const filePath = - __dirname + "/../storage/exports/" + request.params.filename; - response.download(filePath, request.params.filename, (err) => { + const exportLocation = __dirname + "/../storage/exports/"; + const sanitized = path + .normalize(request.params.filename) + .replace(/^(\.\.(\/|\\|$))+/, ""); + const finalDestination = path.join(exportLocation, sanitized); + + if (!fs.existsSync(finalDestination)) { + response.status(404).json({ + error: 404, + msg: `File ${request.params.filename} does not exist in exports.`, + }); + return; + } + + response.download(finalDestination, request.params.filename, (err) => { if (err) { response.send({ error: err, @@ -448,13 +461,11 @@ function systemEndpoints(app) { response.status(200).json({ canDelete }); } catch (error) { console.error("Error fetching can delete workspaces:", error); - response - .status(500) - .json({ - success: false, - message: "Internal server error", - canDelete: false, - }); + response.status(500).json({ + success: false, + message: "Internal server error", + canDelete: false, + }); } } ); -- GitLab