Merge pull request #939 from NimbusPulse/fix/frontend-path-traversal

Frontend: Fix possible path traversal
This commit is contained in:
Pax1601
2024-11-10 09:14:49 +01:00
committed by GitHub

View File

@@ -4,56 +4,79 @@ module.exports = function (databasesLocation) {
const fs = require("fs"); const fs = require("fs");
const path = require("path"); const path = require("path");
function securePath(base, ...parts) {
const fullPath = path.resolve(base, ...parts);
const resolvedBase = path.resolve(base);
if (!fullPath.startsWith(resolvedBase)) {
throw new Error("Invalid path");
}
return fullPath;
}
router.get('/:type/:name', function (req, res) { router.get('/:type/:name', function (req, res) {
var contents = fs.readFileSync(path.join(databasesLocation, req.params.type, req.params.name + ".json")); try {
res.status(200).send(contents); const filePath = securePath(databasesLocation, req.params.type, req.params.name + ".json");
const contents = fs.readFileSync(filePath);
res.status(200).send(contents);
} catch (error) {
res.status(404).send('Not found');
}
}); });
router.put('/save/:type/:name', function (req, res) { router.put('/save/:type/:name', function (req, res) {
var dir = path.join(databasesLocation, req.params.type, "old"); try {
if (!fs.existsSync(dir)) { const dir = securePath(databasesLocation, req.params.type, "old");
fs.mkdirSync(dir); if (!fs.existsSync(dir)) {
} fs.mkdirSync(dir, { recursive: true });
var filepath = path.join(databasesLocation, req.params.type, req.params.name + ".json");
if (fs.existsSync(filepath)) {
var newFilepath = path.join(databasesLocation, req.params.type, "old", req.params.name + ".json");
fs.copyFileSync(filepath, newFilepath);
if (fs.existsSync(newFilepath)) {
try {
var json = JSON.stringify(req.body.blueprints, null, "\t");
fs.writeFileSync(filepath, json, 'utf8');
res.send("OK");
} catch {
res.status(422).send("Error");
}
} else {
res.status(422).send("Error");
} }
} else {
res.status(404).send('Not found'); const filePath = securePath(databasesLocation, req.params.type, req.params.name + ".json");
const backupPath = securePath(databasesLocation, req.params.type, "old", req.params.name + ".json");
if (fs.existsSync(filePath)) {
fs.copyFileSync(filePath, backupPath);
const json = JSON.stringify(req.body.blueprints, null, "\t");
fs.writeFileSync(filePath, json, 'utf8');
res.send("OK");
} else {
res.status(404).send('Not found');
}
} catch (error) {
res.status(422).send("Error");
} }
}); });
router.put('/reset/:type/:name', function (req, res) { router.put('/reset/:type/:name', function (req, res) {
var filepath = path.join(databasesLocation, req.params.type, "default", req.params.name + ".json"); try {
if (fs.existsSync(filepath)) { const defaultPath = securePath(databasesLocation, req.params.type, "default", req.params.name + ".json");
var newFilepath = path.join(databasesLocation, req.params.type, req.params.name + ".json"); const targetPath = securePath(databasesLocation, req.params.type, req.params.name + ".json");
fs.copyFileSync(filepath, newFilepath);
res.send("OK"); if (fs.existsSync(defaultPath)) {
} else { fs.copyFileSync(defaultPath, targetPath);
res.status(404).send('Not found'); res.send("OK");
} else {
res.status(404).send('Not found');
}
} catch (error) {
res.status(422).send("Error");
} }
}); });
router.put('/restore/:type/:name', function (req, res) { router.put('/restore/:type/:name', function (req, res) {
var filepath = path.join(databasesLocation, req.params.type, "old", req.params.name + ".json"); try {
if (fs.existsSync(filepath)) { const backupPath = securePath(databasesLocation, req.params.type, "old", req.params.name + ".json");
var newFilepath = path.join(databasesLocation, req.params.type, req.params.name + ".json"); const targetPath = securePath(databasesLocation, req.params.type, req.params.name + ".json");
fs.copyFileSync(filepath, newFilepath);
res.send("OK"); if (fs.existsSync(backupPath)) {
} else { fs.copyFileSync(backupPath, targetPath);
res.status(404).send('Not found'); res.send("OK");
} else {
res.status(404).send('Not found');
}
} catch (error) {
res.status(422).send("Error");
} }
}); });