From fcc808c84c2cc3afb343063e32a49440d32a553c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Rengel=20Jim=C3=A9nez?= Date: Fri, 14 Apr 2023 16:42:32 +0200 Subject: [PATCH] fix: add extra security to file endpoints (#5090) --- packages/backend/src/routers/projectRouter.ts | 19 +++++++++---------- packages/backend/src/routers/slackRouter.ts | 12 +++++++++--- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/packages/backend/src/routers/projectRouter.ts b/packages/backend/src/routers/projectRouter.ts index c064e0364991..e5d3d398266a 100644 --- a/packages/backend/src/routers/projectRouter.ts +++ b/packages/backend/src/routers/projectRouter.ts @@ -242,21 +242,20 @@ projectRouter.get( async (req, res, next) => { try { - if (!req.params.fileId.startsWith('csv-')) { - throw new NotFoundError( - `CSV file not found ${req.params.fileId}`, - ); + const { fileId } = req.params; + + if (!fileId.startsWith('csv-') || !fileId.endsWith('.csv')) { + throw new NotFoundError(`CSV file not found ${fileId}`); } - const filePath = path.join('/tmp', req.params.fileId); + const sanitizedFileId = fileId.replace('..', ''); + + const filePath = path.join('/tmp', sanitizedFileId); if (!fs.existsSync(filePath)) { - const error = `This file ${req.params.fileId} doesn't exist on this server, this may be happening if you are running multiple containers or because files are not persisted. You can check out our docs to learn more on how to enable cloud storage: https://docs.lightdash.com/self-host/customize-deployment/configure-lightdash-to-use-external-object-storage`; + const error = `This file ${fileId} doesn't exist on this server, this may be happening if you are running multiple containers or because files are not persisted. You can check out our docs to learn more on how to enable cloud storage: https://docs.lightdash.com/self-host/customize-deployment/configure-lightdash-to-use-external-object-storage`; throw new NotFoundError(error); } res.set('Content-Type', 'text/csv'); - res.set( - 'Content-Disposition', - `attachment; filename=${req.params.fileId}`, - ); + res.set('Content-Disposition', `attachment; filename=${fileId}`); res.sendFile(filePath); } catch (error) { next(error); diff --git a/packages/backend/src/routers/slackRouter.ts b/packages/backend/src/routers/slackRouter.ts index 00b5a8646ae2..d9f91314c634 100644 --- a/packages/backend/src/routers/slackRouter.ts +++ b/packages/backend/src/routers/slackRouter.ts @@ -58,14 +58,20 @@ slackRouter.get( async (req, res, next) => { try { - if (!req.params.imageId.startsWith('slack-image')) { + const { imageId } = req.params; + if ( + !imageId.startsWith('slack-image') || + !imageId.endsWith('.png') + ) { throw new NotFoundError( `Slack image not found ${req.params.imageId}`, ); } - const filePath = path.join('/tmp', req.params.imageId); + const sanitizedImageId = imageId.replace('..', ''); + + const filePath = path.join('/tmp', sanitizedImageId); if (!fs.existsSync(filePath)) { - const error = `This file ${req.params.imageId} doesn't exist on this server, this may be happening if you are running multiple containers or because files are not persisted. You can check out our docs to learn more on how to enable cloud storage: https://docs.lightdash.com/self-host/customize-deployment/configure-lightdash-to-use-external-object-storage`; + const error = `This file ${imageId} doesn't exist on this server, this may be happening if you are running multiple containers or because files are not persisted. You can check out our docs to learn more on how to enable cloud storage: https://docs.lightdash.com/self-host/customize-deployment/configure-lightdash-to-use-external-object-storage`; throw new NotFoundError(error); } res.sendFile(filePath);