CVE-2022-1752 (JavaScript, published 2022-05-21T03:15Z)
Description: value: Unrestricted Upload of File with Dangerous Type in GitHub repository polonel/trudesk prior to 1.2.2.
Severity: MEDIUM (CVSS v3 base score: 8)
Weakness: CWE-434 \u2014 Unrestricted Upload of File with Dangerous Type
The product allows the upload or transfer of dangerous file types that are automatically processed within its environment.
Repository: https://github.com/polonel/trudesk
Files changed:
src/controllers/accounts.js
src/controllers/api/v1/routes.js
src/controllers/api/v1/users.js
Commit message: refactor(accounts): security enhancements

Vulnerable code:
    if (mimetype.indexOf('image/') === -1 || ext === '.svg') {
    object.filePath = path.join(savePath, 'aProfile_' + object.username + path.extname(filename))
  router.post('/api/v1/users/:username/uploadprofilepic', apiv1, apiCtrl.users.uploadProfilePic)
apiUsers.uploadProfilePic = function (req, res) {
  const fs = require('fs')
  const path = require('path')
  const Busboy = require('busboy')
  const busboy = Busboy({
    headers: req.headers,
    limits: {
      files: 1,
      fileSize: 1024 * 1024 * 3
    }
  })

  const object = {}
  let error

  if (_.isUndefined(req.params.username)) return res.status(400).json({ error: 'Invalid Username' })
  object.username = req.params.username

  busboy.on('file', function (name, file, info) {
    const mimetype = info.mimeType

    if (mimetype.indexOf('image/') === -1) {
      error = {
        status: 400,
        message: 'Invalid file type'
      }

      return file.resume()
    }

    const savePath = path.join(__dirname, '../../../../public/uploads/users')
    if (!fs.existsSync(savePath)) fs.mkdirSync(savePath)

    object.filePath = path.join(savePath, 'aProfile_' + object.username + '.jpg')
    object.filename = 'aProfile_' + object.username + '.jpg'
    object.mimetype = mimetype

    file.on('limit', function () {
      error = {
        status: 400,
        message: 'File too large'
      }

      return file.resume()
    })

    file.pipe(fs.createWriteStream(object.filePath))
  })

  busboy.on('finish', function () {
    if (error) return res.status(error.status).send(error.message)

    if (_.isUndefined(object.username) || _.isUndefined(object.filePath) || _.isUndefined(object.filename)) {
      return res.status(400).send('Invalid Form Data')
    }

    if (!fs.existsSync(object.filePath)) return res.status(400).send('File failed to save to disk')

    UserSchema.getUserByUsername(object.username, function (err, user) {
      if (err) return res.status(400).send(err.message)

      user.image = object.filename

      user.save(function (err) {
        if (err) return res.status(500).send(err.message)

        emitter.emit('trudesk:profileImageUpdate', {
          userid: user._id,
          img: user.image
        })

        return res.json({ success: true, user: stripUserFields(user) })
      })
    })
  })

  req.pipe(busboy)
}


Fixed code:
const path = require('path')
  const allowedExts = ['.png', '.jpg', '.jpeg', '.gif']


    if (!allowedExts.includes(ext)) {
    object.filename = object.filename.replace('/', '').replace('..', '')
    object.filePath = path.join(savePath, object.filename)