prevent exports path traversal (#233)

This commit is contained in:
Timothy Carambat 2023-09-11 22:07:48 +02:00 committed by GitHub
parent 0fd46e10ac
commit 3c88aec034
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 12 deletions

View File

@ -177,7 +177,8 @@ export default function DocumentSettings({ workspace }) {
</div> </div>
</div> </div>
<div <div
className={`flex items-center ${canDelete ? "justify-between" : "justify-end" 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`} } p-4 md:p-6 space-x-2 border-t border-gray-200 rounded-b dark:border-gray-600`}
> >
<button <button

View File

@ -24,6 +24,7 @@ const { User } = require("../models/user");
const { validatedRequest } = require("../utils/middleware/validatedRequest"); const { validatedRequest } = require("../utils/middleware/validatedRequest");
const { handleImports } = setupDataImports(); const { handleImports } = setupDataImports();
const { handleLogoUploads } = setupLogoUploads(); const { handleLogoUploads } = setupLogoUploads();
const fs = require("fs");
const path = require("path"); const path = require("path");
const { const {
getDefaultFilename, getDefaultFilename,
@ -315,9 +316,21 @@ function systemEndpoints(app) {
"/system/data-exports/:filename", "/system/data-exports/:filename",
[validatedRequest], [validatedRequest],
(request, response) => { (request, response) => {
const filePath = const exportLocation = __dirname + "/../storage/exports/";
__dirname + "/../storage/exports/" + request.params.filename; const sanitized = path
response.download(filePath, request.params.filename, (err) => { .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) { if (err) {
response.send({ response.send({
error: err, error: err,
@ -448,9 +461,7 @@ function systemEndpoints(app) {
response.status(200).json({ canDelete }); response.status(200).json({ canDelete });
} catch (error) { } catch (error) {
console.error("Error fetching can delete workspaces:", error); console.error("Error fetching can delete workspaces:", error);
response response.status(500).json({
.status(500)
.json({
success: false, success: false,
message: "Internal server error", message: "Internal server error",
canDelete: false, canDelete: false,