Merge pull request #1470 from valadaptive/sanitize-cleanup

Clean up file name sanitization
This commit is contained in:
Cohee 2023-12-05 16:45:00 +02:00 committed by GitHub
commit 6ea9269592
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 10 additions and 15 deletions

View File

@ -15,19 +15,14 @@ const VALID_CATEGORIES = ['bgm', 'ambient', 'blip', 'live2d'];
* @param {string} inputFilename Input filename
* @returns {string} Normalized or empty path if invalid
*/
function checkAssetFileName(inputFilename) {
// Sanitize filename
if (inputFilename.indexOf('\0') !== -1) {
console.debug('Bad request: poisong null bytes in filename.');
return '';
}
function sanitizeAssetFileName(inputFilename) {
if (!/^[a-zA-Z0-9_\-.]+$/.test(inputFilename)) {
console.debug('Bad request: illegal character in filename, only alphanumeric, \'_\', \'-\' are accepted.');
return '';
}
if (UNSAFE_EXTENSIONS.some(ext => inputFilename.toLowerCase().endsWith(ext))) {
const inputExtension = path.extname(inputFilename).toLowerCase();
if (UNSAFE_EXTENSIONS.some(ext => ext === inputExtension)) {
console.debug('Bad request: forbidden file extension.');
return '';
}
@ -37,7 +32,7 @@ function checkAssetFileName(inputFilename) {
return '';
}
return path.normalize(inputFilename).replace(/^(\.\.(\/|\\|$))+/, '');
return inputFilename;
}
// Recursive function to get files
@ -144,7 +139,7 @@ router.post('/download', jsonParser, async (request, response) => {
}
// Sanitize filename
const safe_input = checkAssetFileName(inputFilename);
const safe_input = sanitizeAssetFileName(inputFilename);
if (safe_input == '')
return response.sendStatus(400);
@ -203,7 +198,7 @@ router.post('/delete', jsonParser, async (request, response) => {
}
// Sanitize filename
const safe_input = checkAssetFileName(inputFilename);
const safe_input = sanitizeAssetFileName(inputFilename);
if (safe_input == '')
return response.sendStatus(400);
@ -305,7 +300,7 @@ router.post('/upload', jsonParser, async (request, response) => {
return response.status(400).send('No upload data specified');
}
const safeInput = checkAssetFileName(request.body.name);
const safeInput = sanitizeAssetFileName(request.body.name);
if (!safeInput) {
return response.status(400).send('Invalid upload name');
@ -321,4 +316,4 @@ router.post('/upload', jsonParser, async (request, response) => {
}
});
module.exports = { router, checkAssetFileName };
module.exports = { router, sanitizeAssetFileName };

View File

@ -2,7 +2,7 @@ const path = require('path');
const writeFileSyncAtomic = require('write-file-atomic').sync;
const express = require('express');
const router = express.Router();
const { checkAssetFileName } = require('./assets');
const { sanitizeAssetFileName } = require('./assets');
const { jsonParser } = require('../express-common');
const { DIRECTORIES } = require('../constants');
@ -16,7 +16,7 @@ router.post('/upload', jsonParser, async (request, response) => {
return response.status(400).send('No upload data specified');
}
const safeInput = checkAssetFileName(request.body.name);
const safeInput = sanitizeAssetFileName(request.body.name);
if (!safeInput) {
return response.status(400).send('Invalid upload name');