Improve asset downloader

This commit is contained in:
Cohee 2023-08-24 22:47:07 +03:00
parent 3b6978010f
commit 48924d3696
2 changed files with 93 additions and 2 deletions

View File

@ -5070,7 +5070,7 @@ app.post('/asset_download', jsonParser, async (request, response) => {
const url = request.body.url; const url = request.body.url;
const inputCategory = request.body.category; const inputCategory = request.body.category;
const inputFilename = sanitize(request.body.filename); const inputFilename = sanitize(request.body.filename);
const validCategories = ["bgm", "ambient"] const validCategories = ["bgm", "ambient"];
// Check category // Check category
let category = null let category = null
@ -5094,6 +5094,16 @@ app.post('/asset_download', jsonParser, async (request, response) => {
return response.sendStatus(400); return response.sendStatus(400);
} }
if (contentManager.unsafeExtensions.some(ext => inputFilename.toLowerCase().endsWith(ext))) {
console.debug("Bad request: forbidden file extension.");
return response.sendStatus(400);
}
if (inputFilename.startsWith('.')) {
console.debug("Bad request: filename cannot start with '.'");
return response.sendStatus(400);
}
const safe_input = path.normalize(inputFilename).replace(/^(\.\.(\/|\\|$))+/, ''); const safe_input = path.normalize(inputFilename).replace(/^(\.\.(\/|\\|$))+/, '');
const temp_path = path.join(directories.assets, "temp", safe_input) const temp_path = path.join(directories.assets, "temp", safe_input)
const file_path = path.join(directories.assets, category, safe_input) const file_path = path.join(directories.assets, category, safe_input)
@ -5103,6 +5113,9 @@ app.post('/asset_download', jsonParser, async (request, response) => {
// Download to temp // Download to temp
const downloadFile = (async (url, temp_path) => { const downloadFile = (async (url, temp_path) => {
const res = await fetch(url); const res = await fetch(url);
if (!res.ok) {
throw new Error(`Unexpected response ${res.statusText}`);
}
const destination = path.resolve(temp_path); const destination = path.resolve(temp_path);
// Delete if previous download failed // Delete if previous download failed
if (fs.existsSync(temp_path)) { if (fs.existsSync(temp_path)) {

View File

@ -5,6 +5,83 @@ const contentDirectory = path.join(process.cwd(), 'default/content');
const contentLogPath = path.join(contentDirectory, 'content.log'); const contentLogPath = path.join(contentDirectory, 'content.log');
const contentIndexPath = path.join(contentDirectory, 'index.json'); const contentIndexPath = path.join(contentDirectory, 'index.json');
const unsafeExtensions = [
".php",
".exe",
".com",
".dll",
".pif",
".application",
".gadget",
".msi",
".jar",
".cmd",
".bat",
".reg",
".sh",
".py",
".js",
".jse",
".jsp",
".pdf",
".html",
".htm",
".hta",
".vb",
".vbs",
".vbe",
".cpl",
".msc",
".scr",
".sql",
".iso",
".img",
".dmg",
".ps1",
".ps1xml",
".ps2",
".ps2xml",
".psc1",
".psc2",
".msh",
".msh1",
".msh2",
".mshxml",
".msh1xml",
".msh2xml",
".scf",
".lnk",
".inf",
".reg",
".doc",
".docm",
".docx",
".dot",
".dotm",
".dotx",
".xls",
".xlsm",
".xlsx",
".xlt",
".xltm",
".xltx",
".xlam",
".ppt",
".pptm",
".pptx",
".pot",
".potm",
".potx",
".ppam",
".ppsx",
".ppsm",
".pps",
".ppam",
".sldx",
".sldm",
".ws",
];
function checkForNewContent() { function checkForNewContent() {
try { try {
if (config.skipContentCheck) { if (config.skipContentCheck) {
@ -85,4 +162,5 @@ function getContentLog() {
module.exports = { module.exports = {
checkForNewContent, checkForNewContent,
unsafeExtensions,
} }