0

I'm building a very simple endpoint to change a user's profile photo and can't find detailed information on how to verify an uploaded file is a real image. On the server, I can easily filter out requests to my endpoint based on the Content-Type header; if the header is not one of the types I'm enforcing, then return a 400. Consider that I only want to receive images that are png, jpg or jpeg; my endpoint would have a condition as shown below:

const validImageMimeTypes = ['image/jpeg', 'image/jpg', 'image/png']

router.put('/:id/avatar', (req, res) => {
  if (!validImageMimeTypes.includes(req.get('content-type'))) {
    res.status(400)
    res.send("Unsupported file type")
    return
  }
  ...
}

This is great, but it doesn't prevent an user from changing the extension of a file to one of the enforced ones and uploading it. I tried doing exactly this with my Github avatar picture, and their server-side was able to pick up on the fact that what I uploaded wasn't a real image:

{"message":"Expected formats \"png,jpg,gif\", got \"unknown\"",
 "request_id":"F5F0:365D:1EC5D9:226D70:5C94E2AB",
 "errors":[{"resource":"upload","code":"content_mismatch","field":"format"}]}

In general terms, how did they implement this validation? Are they using a library to obtain simple attributes from the image such as size and width, and if that fails return a 400? Any industry practices I should be aware of?

Thanks

macalaca
  • 988
  • 1
  • 13
  • 31

1 Answers1

0

I found a JavaScript package to do exactly what I need. It's actively maintained and works well for the file types I need to check.

macalaca
  • 988
  • 1
  • 13
  • 31