0

This multer configuration lets me upload images with '.gif' format. How to solve this ? I want it to only upload png, jpg, jpeg

This is my code:

let storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, '/public/images')
    },
    filename: function (req, file, cb) {
        crypto.pseudoRandomBytes(16, function (err, raw) {
            cb(null, raw.toString('hex') + Date.now() + '.' + mime.getExtension(file.mimetype));
        });
    }
});
let upload = multer({
    limits: {
        fileSize: 1000000
    },
    fileFilter: function(req, file, cb) {
        if(!file.originalname.match(/\.(jpg|jpeg|png)$/)){
            return cb('File must be an image.');
        }
        cb(undefined, true);
    },
    storage: storage
});

Route:

app.post('/upload-ad', upload.any(), recaptcha.middleware.verify, (req, res)
Don
  • 503
  • 1
  • 4
  • 14
zlotte
  • 221
  • 1
  • 11
  • Possible duplicate of [Filter files on the basis of extension using Multer in Express JS](https://stackoverflow.com/questions/38652848/filter-files-on-the-basis-of-extension-using-multer-in-express-js) – TGrif Mar 19 '19 at 09:08

1 Answers1

0

If I test your code like below, I get the correct response, e.g. "File must be an image." if I try to upload a .gif file.

const request = require("request");
const fs = require("fs");

const options = {
    method: "POST",
    url: "http://localhost:3300/upload-ad",
    headers: {
        "Content-Type": "multipart/form-data"
    },
    formData : {
        "image" : fs.createReadStream("./test.gif")
    }
};

request(options, function (err, res, body) {
    if(err) console.log(err);
    console.log(body);
});

This works because we're setting the Content-Disposition field in this case. I suspect that what's happening to you is that maybe the client is not setting this header, or it was set incorrectly. For example if we changed a filename from "test.gif" to "test.jpg" this would upload successfully despite the fact it is actually a GIF image.

In my case the start of the upload looks like so:

----------------------------321622124424983663382061
Content-Disposition: form-data; name="image"; filename="test.gif"
Content-Type: image/gif

And everything works as it is supposed to.

I'd recommend maybe not trusting the filename field in the POST and actually check what the image really is by looking at the uploaded buffer.

Terry Lennox
  • 29,471
  • 5
  • 28
  • 40