From c9d88e7d26d645bf272ceff2ec05a6b8b63ea4bb Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Fri, 15 Mar 2024 09:59:20 +0000 Subject: [PATCH] handle different content-disposition and potential path traversal --- packages/backend-core/src/objectStore/utils.ts | 2 +- packages/server/package.json | 1 + packages/server/src/integrations/rest.ts | 7 ++++--- yarn.lock | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/backend-core/src/objectStore/utils.ts b/packages/backend-core/src/objectStore/utils.ts index 3e7ac7d321..a2d4c694c9 100644 --- a/packages/backend-core/src/objectStore/utils.ts +++ b/packages/backend-core/src/objectStore/utils.ts @@ -37,7 +37,7 @@ export const bucketTTLConfig = ( days: number ): PutBucketLifecycleConfigurationRequest => { const lifecycleRule = { - ID: "ExpireAfterOneDay", + ID: `${bucketName}-ExpireAfterOneDay`, Prefix: "", Status: "Enabled", Expiration: { diff --git a/packages/server/package.json b/packages/server/package.json index 777ecba2a7..a72852b9ba 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -67,6 +67,7 @@ "bcryptjs": "2.4.3", "bull": "4.10.1", "chokidar": "3.5.3", + "content-disposition": "^0.5.4", "cookies": "0.8.0", "csvtojson": "2.0.10", "curlconverter": "3.21.0", diff --git a/packages/server/src/integrations/rest.ts b/packages/server/src/integrations/rest.ts index 308ebf035d..dff365d84d 100644 --- a/packages/server/src/integrations/rest.ts +++ b/packages/server/src/integrations/rest.ts @@ -22,6 +22,8 @@ import FormData from "form-data" import { URLSearchParams } from "url" import { blacklist } from "@budibase/backend-core" import { handleFileResponse, handleXml } from "./utils" +import { parse } from "content-disposition" +import path from "path" const BodyTypes = { NONE: "none", @@ -134,9 +136,8 @@ class RestIntegration implements IntegrationBase { const contentType = response.headers.get("content-type") || "" const contentDisposition = response.headers.get("content-disposition") || "" - const matches = - /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/.exec(contentDisposition) || [] - filename = matches[1]?.replace(/['"]/g, "") || "" + filename = + path.basename(parse(contentDisposition).parameters?.filename) || "" try { if (filename) { diff --git a/yarn.lock b/yarn.lock index 22b9e41e16..6f3df1f87d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8570,7 +8570,7 @@ consolidate@^0.16.0: dependencies: bluebird "^3.7.2" -content-disposition@^0.5.2, content-disposition@^0.5.3, content-disposition@~0.5.2: +content-disposition@^0.5.2, content-disposition@^0.5.3, content-disposition@^0.5.4, content-disposition@~0.5.2: version "0.5.4" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==