Skip to content

Commit 227ffc1

Browse files
author
Sammy Ndabo
committed
enh: filename validation in upload handler to prevent path traversal
1 parent 7f01837 commit 227ffc1

File tree

1 file changed

+10
-4
lines changed

1 file changed

+10
-4
lines changed

webserver.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4632,7 +4632,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
46324632
var names = fields.name[0].split('*'), sizes = fields.size[0].split('*'), types = fields.type[0].split('*'), datas = fields.data[0].split('*');
46334633
if ((names.length == sizes.length) && (types.length == datas.length) && (names.length == types.length)) {
46344634
for (var i = 0; i < names.length; i++) {
4635-
if (obj.common.IsFilenameValid(names[i]) == false) { res.sendStatus(404); return; }
4635+
var originalName = names[i];
4636+
var safeName = obj.path.basename(originalName);
4637+
if ((safeName !== originalName) || (obj.common.IsFilenameValid(safeName) == false)) { res.sendStatus(404); return; }
46364638
var filedata = Buffer.from(datas[i].split(',')[1], 'base64');
46374639
if ((xfile.quota == null) || ((totalsize + filedata.length) < xfile.quota)) { // Check if quota would not be broken if we add this file
46384640
// Create the user folder if needed
@@ -4643,7 +4645,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
46434645
obj.parent.DispatchEvent([user._id], obj, 'updatefiles'); // Fire an event causing this user to update this files
46444646
});
46454647
});
4646-
})(xfile.fullpath, names[i], filedata);
4648+
})(xfile.fullpath, safeName, filedata);
46474649
} else {
46484650
// Send a notification
46494651
obj.parent.DispatchEvent([user._id], obj, { action: 'notify', title: "Disk quota exceed", value: names[i], nolog: 1, id: Math.random() });
@@ -4653,8 +4655,12 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
46534655
} else {
46544656
// More typical upload method, the file data is in a multipart mime post.
46554657
for (var i in files.files) {
4656-
var file = files.files[i], fpath = obj.path.join(xfile.fullpath, file.originalFilename);
4657-
if (obj.common.IsFilenameValid(file.originalFilename) && ((xfile.quota == null) || ((totalsize + file.size) < xfile.quota))) { // Check if quota would not be broken if we add this file
4658+
var file = files.files[i];
4659+
var originalFilename = (typeof file.originalFilename === 'string') ? file.originalFilename : '';
4660+
var safeOriginalFilename = obj.path.basename(originalFilename);
4661+
var isFilenameAcceptable = (safeOriginalFilename === originalFilename) && obj.common.IsFilenameValid(safeOriginalFilename);
4662+
if (isFilenameAcceptable && ((xfile.quota == null) || ((totalsize + file.size) < xfile.quota))) { // Check if quota would not be broken if we add this file
4663+
var fpath = obj.path.join(xfile.fullpath, safeOriginalFilename);
46584664

46594665
// See if we need to create the folder
46604666
var domainx = 'domain';

0 commit comments

Comments
 (0)