The recent, highly publicized “ImageTragick” vulnerability had countless web developers scrambling to fix a remote code execution vector in ImageMagick – a popular bitmap manipulation tool commonly used to resize, transcode, or annotate user-supplied images on the Web. Whatever your take on “branded” vulnerabilities may be, the flaw certainly is notable for its ease of exploitation: it is an embarrassingly simple shell command injection bug reminiscent of the security weaknesses prevalent in the 1990s, and nearly extinct in core tools today. The issue also bears some parallels to the more far-reaching but equally striking Shellshock bug.
That said, I believe that the publicity that surrounded the flaw was squandered by failing to make one very important point: even with this particular RCE vector fixed, anyone using ImageMagick to process attacker-controlled images is likely putting themselves at a serious risk.
The problem is fairly simple: for all its virtues, ImageMagick does not appear to be designed with malicious inputs in mind – and has a long and colorful history of lesser-known but equally serious security flaws. For a single data point, look no further than the work done several months ago by Jodie Cunningham. Jodie fuzzed IM with a vanilla setup of afl-fuzz – and quickly identified about two dozen possibly exploitable security holes, along with countless denial of service flaws. A small sample of Jodie’s findings can be found here.
Jodie’s efforts probably just scratched the surface; after “ImageTragick”, a more recent effort by Hanno Boeck uncovered even more bugs; from what I understand, Hanno’s work also went only as far as using off-the-shelf fuzzing tools. You can bet that, short of a major push to redesign the entire IM codebase, the trickle won’t stop any time soon.
And so, the advice sorely missing from the “ImageTragick” webpage is this:
If all you need to do is simple transcoding or thumbnailing of potentially untrusted images, don’t use ImageMagick. Make a direct use of libpng, libjpeg-turbo, and giflib; for a robust way to use these libraries, have a look at the source code of Chromium or Firefox. The resulting implementation will be considerably faster, too.
If you have to use ImageMagick on untrusted inputs, consider sandboxing the code with seccomp-bpf or an equivalent mechanism that robustly restricts access to all user space artifacts and to the kernel attack surface. Rudimentary sandboxing technologies, such as chroot() or UID separation, are probably not enough.
If all other options fail, be zealous about limiting the set of image formats you actually pass down to IM. The bare minimum is to thoroughly examine the headers of the received files. It is also helpful to explicitly specify the input format when calling the utility, as to preempt auto-detection code. For command-line invocations, this can be done like so:
convert [...other params...] -- jpg:input-file.jpg jpg:output-file.jpg
The JPEG, PNG, and GIF handling code in ImageMagick is considerably more robust than the code that supports PCX, TGA, SVG, PSD, and the likes.