diff --git a/package.json b/package.json index 5262349..8c29ebb 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "iconv-lite": "^0.6.2", "koa": "^2.13.1", "koa-body": "^4.2.0", + "koa-send": "^5.0.1", "log4js": "^6.4.0", "node-disk-info": "^1.3.0", "node-schedule": "^2.0.0", @@ -44,17 +45,18 @@ "@types/iconv-lite": "0.0.1", "@types/koa": "^2.13.4", "@types/koa__router": "^8.0.7", + "@types/koa-send": "^4.1.3", "@types/log4js": "^2.3.5", "@types/mocha": "^8.2.2", "@types/node": "^18.11.18", - "@types/ssh2": "^1.11.7", "@types/node-schedule": "^1.3.2", "@types/os-utils": "0.0.1", "@types/pidusage": "^2.0.1", + "@types/ssh2": "^1.11.7", "@types/uuid": "^8.3.0", - "ts-node": "^10.9.1", "eslint": "^7.13.0", "nodemon": "^2.0.20", + "ts-node": "^10.9.1", "typescript": "^4.9.4", "webpack": "^5.73.0", "webpack-cli": "^4.10.0", diff --git a/src/routers/http_router.ts b/src/routers/http_router.ts index 57a1c68..d0d961b 100755 --- a/src/routers/http_router.ts +++ b/src/routers/http_router.ts @@ -2,6 +2,7 @@ import { $t } from "../i18n"; import Router from "@koa/router"; +import send from "koa-send"; import fs from "fs-extra"; import path from "path"; import { missionPassport } from "../service/mission_passport"; @@ -30,17 +31,16 @@ router.get("/download/:key/:fileName", async (ctx) => { const cwd = instance.config.cwd; const fileRelativePath = mission.parameter.fileName; - const ext = path.extname(fileRelativePath); + // Check for file cross-directory security risks const fileManager = new FileManager(cwd); if (!fileManager.check(fileRelativePath)) throw new Error((ctx.body = "Access denied: Invalid destination")); - // start downloading the file to the user - ctx.response.set("Content-Disposition", `attachment; filename="${encodeURIComponent(paramsFileName)}"`); - ctx.type = ext; - ctx.body = fs.createReadStream(fileManager.toAbsolutePath(fileRelativePath)); - // The task has been executed, destroy the passport - missionPassport.deleteMission(key); + // send File + const fileAbsPath = fileManager.toAbsolutePath(fileRelativePath); + const fileDir = path.dirname(fileAbsPath); + const fileName = path.basename(fileAbsPath); + await send(ctx, fileName, { root: fileDir + "/" }); } catch (error) { ctx.body = $t("http_router.downloadErr", { error: error.message }); ctx.status = 500;