diff options
author | David Mehren | 2020-12-27 11:31:01 +0100 |
---|---|---|
committer | David Mehren | 2020-12-27 19:51:12 +0100 |
commit | cf4344d9e031d2e0bf70b8d8f75ab27ecf8d29ad (patch) | |
tree | 002d52ce213dd53e1d9b0465e0335bd7d2004cd2 /lib | |
parent | f83e4d66ed2b6a7f7f8939e2eb63d262387e9374 (diff) |
Improve MIME-type checks of uploaded files
This commit adds a check if the MIME-type of the uploaded file (detected using the magic bytes) matches the file extension.
Signed-off-by: David Mehren <git@herrmehren.de>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/web/imageRouter/index.js | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/lib/web/imageRouter/index.js b/lib/web/imageRouter/index.js index b6ace4a6..5861a2bc 100644 --- a/lib/web/imageRouter/index.js +++ b/lib/web/imageRouter/index.js @@ -2,6 +2,8 @@ const Router = require('express').Router const formidable = require('formidable') +const path = require('path') +const FileType = require('file-type') const config = require('../../config') const logger = require('../../logger') @@ -9,6 +11,23 @@ const errors = require('../../errors') const imageRouter = module.exports = Router() +async function checkUploadType (filePath) { + const typeFromMagic = await FileType.fromFile(filePath) + if (typeFromMagic === undefined) { + logger.error(`Image upload error: Could not determine MIME-type`) + return false + } + if (path.extname(filePath) !== '.' + typeFromMagic.ext) { + logger.error(`Image upload error: Provided file extension does not match MIME-type`) + return false + } + if (!config.allowedUploadMimeTypes.includes(typeFromMagic.mime)) { + logger.error(`Image upload error: MIME-type "${typeFromMagic.mime}" of uploaded file not allowed, only "${config.allowedUploadMimeTypes.join(', ')}" are allowed`) + return false + } + return true +} + // upload image imageRouter.post('/uploadimage', function (req, res) { var form = new formidable.IncomingForm() @@ -19,18 +38,17 @@ imageRouter.post('/uploadimage', function (req, res) { form.uploadDir = config.uploadsPath } - form.parse(req, function (err, fields, files) { + form.parse(req, async function (err, fields, files) { if (err) { logger.error(`Image upload error: formidable error: ${err}`) return errors.errorForbidden(res) - } else if (!req.isAuthenticated() && !config.allowAnonymous && !config.allowAnonymousEdits) { + } else if (!req.isAuthenticated() && !config.allowAnonymous && !config.allowAnonymousEdits) { logger.error(`Image upload error: Anonymous edits and therefore uploads are not allowed)`) return errors.errorForbidden(res) } else if (!files.image || !files.image.path) { logger.error(`Image upload error: Upload didn't contain file)`) return errors.errorBadRequest(res) - } else if (!config.allowedUploadMimeTypes.includes(files.image.type)) { - logger.error(`Image upload error: MIME-type "${files.image.type}" of uploaded file not allowed, only "${config.allowedUploadMimeTypes.join(', ')}" are allowed)`) + } else if (!await checkUploadType(files.image.path)) { return errors.errorBadRequest(res) } else { logger.debug(`SERVER received uploadimage: ${JSON.stringify(files.image)}`) |