I want to find out if it's possible to check if an image file like JPEG, PNG, GIF or BMP is safe and don't have a virus in it.

I want to filter an image file before I send them to sandbox to check if it's not suspicious and I know its safe file. The response from the sandbox takes 2-3 minutes and I want to reduce the time if I can filter some files that definitely clean.

Is there a method to find out if an image file is definitely safe?

  • 1
    How about using virustotal? – pri Mar 15 '18 at 9:46
  • I want to reduce the time before I send it to sandbox, I want to send only files that are maybe suspicious – Max.Futerman Mar 15 '18 at 12:18
  • 1
    Image files are usually considered low-risk because image formats usually don't include executable code. It's usually only a problem if users open them with image viewers which have bugs which can be exploited by bad images. – Philipp Mar 15 '18 at 12:41
  • related: security.stackexchange.com/questions/87194/… – x457812 Mar 15 '18 at 18:23

Images are collections of pixels. Those are usually harmless. They can only be dangerous if they are malformated and the user uses an image viewing software which has a crucial security bug or if they are mistaken for an executable and someone tries to run them.

An easy way which defeats most of these attacks is to re-encode any images on your server. Use a library on your server to decode the images to an in-memory array of RGBA values and then re-encode those values to a new image in the same format. That checks if it is actually a valid image file and should strip any junk data from it.

However, if you do this, be aware that it opens up your server to potential attacks:

  • The library you use to de- and encode the images might have vulnerabilities. So make sure you use one with a good security track record.
  • The image might be a decompression bomb. Most image formats use compression algorithms. Many compression algorithms allow to craft compressed files which generate a humongous amount of data if uncompressed or take a huge amount of computational resources to uncompress. That can be used for resource exhaustion DOS attacks. So make sure you abort the image decoding if it starts to consume too much RAM or takes more than a few milliseconds (unless your image library already does that).

It also has the side-effect that it won't just strip malicious metadata from the image files but also metadata which is beneficial (like color profiles). If you want to preserve certain kinds of metadata, you need to take special care of that.

  • -1 This will not work. The libraries you use to re-encode images are going to be the exact same libraries as you use to view the image. Unless you are re-encoding them to a trivial format like PPM on an airgapped system, this technique is useless. What you do want is a sandboxed image converter (e.g. with a syscall filter, no X11 or filesystem access, etc) to convert to a pixmap, then have another image encoder (in a separate address space) convert it into the original format. – forest Mar 16 '18 at 3:55
  • Note also that decompression bombs do not work for images. They only work when compression is applied recursively to an archive, not lossy JPEG or DEFLATE compression to internal components of an image. – forest Mar 16 '18 at 3:55

There are a few questions to address here:

Firstly, the real file type. You need to check the file extension but that doesn't necessarily indicate the real file type, you need to check the file type indicator - the "magic bytes", there are libraries for many development platforms to do this for you and you can read more about it here.

On virus scanning, you can either run a scanning engine on a server and submit files to that or you can use an API like Virus Total. There are a few issues to consider with sending the file out to an API.

Where is the API located? Is it in the same country as you, there may be data law restrictions on sending the file out to a scan engine in another country if those images may contain personal information (like faces, names, email addresses etc)

Files uploaded to certain scan engines may be available to other people, consider if this presents any problems for you or your users. You can mitigate this by running your own 'on-prem' system but this will require infrastructure to run and possibly incur additional licensing.

The second consideration is when do you scan? If a user uploads an image, do you scan on demand as soon as they attempt an upload? This will cause a delay in the upload but prevent any viruses getting into your file storage. The alternative is to allow uploads without scanning first and have an agent that runs, scanning files, removing problem files as it goes. It depends on the requirements you have.

  • Sorry, I did not explain the question well, I send the files to sandbox that I have but it takes 2-3 minutes to get a response. I want to reduce the time if I knew that some files are safe therefore lower the number of files that i send to the sandbox. – Max.Futerman Mar 15 '18 at 12:24
  • A virus scanner is unlikely to detect a malicious image file. – forest Mar 16 '18 at 4:17

It is not possible to verify with certainty that an image is clean, short of manually analyzing it to see if it conforms perfectly to the standards, and that your image viewer likewise conforms to the standards. Instead, you can encode the image between a simple format. Converting an image to a trivial format carries with it the risk of exploitation, but converting from a trivial format to a more complex format does not. You can exploit this reduced attack surface area, for example:

  1. Load the suspect image into a sandboxed image converter. The image converter must not have any filesystem access, X11 access, or access to unnecessary syscalls. The sandboxed image converter must be untrusted as it will be using potentially vulnerable libraries.

  2. Have the sandboxed image converter re-encode the image into a trivial pixelmap format, such as PPM. The format must be simple enough that it would be infeasible to exploit. The assumption is that this conversion process may compromise the converter, so all subsequent steps must not need to trust this stage. A pixmap is trivial enough for these purposes.

  3. A second, unsandboxed image converter then takes hold of the pixmap, e.g. through shared memory. This image converter is trusted, as its only input will be a format so trivial that exploitation is infeasible. The pixmap can then be converted into a more proper image format, assuming of course you do not want the output to be a large, uncompressed, raw image.

So why not just have a single sandboxed process convert the image? If you assume that the image parsing library for the input is vulnerable, then even a sandboxed process can no longer be trusted. If you ask it to convert a JPEG to a PNG and the JPEG is malicious, it could embed a different exploit into the PNG output. This is not going to be likely, but it is possible, making this a no-go.

If this is overkill, then there are still some other, simpler ways to decrease the likelihood of falling victim to an image parsing exploit. A non-exhaustive list of recommendations is:

  • Keep all your software up to date, especially image libraries.

  • Verify that the image format matches the extension, e.g. by checking the MIME type.

  • Do not accept images from untrusted sources if possible.

  • Use only common image formats such as JPEG, PNG, and GIF.

  • When you say sandbox, is that essentially running the encoder as another user with minimal access rights? You also mentioned killing the encoder if it takes too much RAM/CPU, any suggested methods/tools to do that? – dvtan Feb 8 at 12:02
  • @dtgq On Linux, you can set resource limits using PAM. – forest Feb 12 at 3:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.