How an uploaded image could take over your website, and how to stop it

Vulnerability hunter Tavis Ormandy just reported a series of security problems in an application called Ghostscript.

Ormandy works for Google’s Project Zero – he literally finds bugs for a living – and his work is both well-known and renowned…

…but who or what is Ghostscript, and why would someone as skilled as Ormandy feel the need to dig into it?

Well, for many people, Ghostscript is software they’ve never heard of, but probably use or rely upon regularly without even realising it.

Ghostscript is a free, open source implementation of Adobe PostScript, a programming language and ecosystem that powers many printers, and that is the technical underpinning to almost every PDF file out there.

Indeed, if you open a PDF file, or generate one, you’re almost certainly firing up a PostScript runtime environment to execute a PostScript program that describes the document.

Many open source toolkits – image editors, document creators, illustration packages, PDF viewers and more – rely on Ghostscript to do the heavy lifting of text and graphics rendering.

In other words, whether you know it or not, you probably used Ghostscript recently, if not locally on your own computer then remotely on someone else’s servers when you used a cloud service.

Remote code execution and data leakage bugs in Ghostscript are therefore worth knowing about, even if they don’t put you in immediate danger and you have to rely on someone else to sort them out.

Ormandy’s vulnerabilities cover a range of security holes, including the ability to:

  • Run shell commands of your choice.
  • Create files in directories you’re not supposed to access.
  • Delete files even if you only have read permission.
  • Extract data from files for which you have no permission.

Ormandy’s bugs require you to feed an installed Ghoscript engine (known in the trade as an interpreter, because it interprets and makes sense of Ghostscript code) with a malicious input file of your own devising, so at first sight the bugs don’t really sound too bad.

After all, if you can download an arbitrary file and then get it launched in a fashion of your own choosing, you could already run malware in a wide range of languages.

On a Mac, for example, you could choose by default from preinstalled versions of Perl, Python, Ruby, PHP, Tcl, Bash, AppleScript and more; on Windows you could run code in Visual Basic Script, JavaScript or Powershell, right off the bat….

…or you could just download or build a compiled malware binary and run it directly.

Nevertheless, even if it’s your own computer and you’re allowed to install new programs, your regular account is supposed to be blocked from reading or deleting files belonging to other users, so bugs of this sort represent Elevation of Privilege (EoP) vulnerabilities.

The bigger problem

But there’s a bigger problem here, caused by the way Ghostcript is often used – it’s not usually treated as a programming language like Perl or Python, but as a mechanism for converting graphics or printing documents.

If someone sends you a document file for printing, or an image file for conversion, you’re supposed to be able to feed it without too much worry into the relevant rendering app for processing – and that app might be Ghostscript.

Ghostscript even has a special setting, activated with the command line option -dSAFER, that acts as a kind of sandbox to limit the damage that a rogue image or document can do, but Ormandy’s latest vulnerabilities can wriggle out from under the SAFER restrictions.

And many servers, notably those running blogs and forums, include and use Ghostscript – whether the company running those services realises it or not.

For example, many blogging and social networking sites allow you to upload your own images, and will automatically rework the files you upload so that they fit the formatting and rendering requirements of the site.

These reformatting changes typically include converting the file to a chosen file format, scaling it to a standard set of sizes, applying colour filters, adding copyright or other messages, compressing it to save space, and more. (The jargon word for this is step is transcoding.)

Very often, a ubiquitous command line tool called ImageMagick is used for this purpose, meaning that the ImageMagick utility is regularly expected to ingest and safely process untrusted files uploaded from outside…

…and ImageMagick, by default, uses Ghostscript in its transcoding process, if it enounters PostScript content.

Therefore an exploitable security hole in Ghostscript often means a hole in ImageMagick, and a hole in ImageMagick may very well mean an externally exposed hole in your content management system, blogging server or online forum.

What to do?

Ghostscript, it seems, is still working through Ormandy’s latest bugs, so there isn’t an update available yet.

But one of the most likely ways you’d be affected by one of these bugs, at least by remote content uploaded to attack you on purpose, is via ImageMagick.

You can therefore use ImageMagick’s configurations settings to help limit your exposure.

For example, you can turn off ImageMagick’s ability to process PostScript files (and the similar, related, file format known as Encapsulated PostScript) altogether, unless you’re certain you need to handle files of that type.

By default, ImageMagick will render PS and EPS files if presented with PostScript data, but you can change that through policy.xml, one of ImageMagick’s configuration files.

To find out where your policy.xml lives, try this:

   $ identify -list configure | grep CONFIGURE-PATH
   CONFIGURE_PATH /usr/local/etc/ImageMagick-7/

To find out what file formats your ImageMagick supports that you can selectively turn off:

   $ identify -list format
     Format  Mode  Description
        3FR  r--   Hasselblad CFV/H3D39II
        3G2  r--   Media Container
        3GP  r--   Media Container
       . . . .
        EPS  rw-   Encapsulated PostScript
       EPS2* -w-   Level II Encapsulated PostScript
       EPS3* -w+   Level III Encapsulated PostScript
       EPSF  rw-   Encapsulated PostScript
       . . . .
        PDF  rw+   Portable Document Format
       PDFA  rw+   Portable Document Archive Format
       . . . .
         PS  rw+   PostScript
        PS2* -w+   Level II PostScript
        PS3* -w+   Level III PostScript
       . . . . 
     YCbCrA* rw+   Raw Y, Cb, Cr, and alpha samples
        YUV* rw-   CCIR 601 4:1:1 or 4:2:2
       . . . .
     * native blob support
     r read support
     w write support
     + support for multiple images

To turn off handling of individual formats, add one or more lines like this to policy.xml:

   <policy domain="coder" rights="none" pattern="{EPS,PS,PDF,PDFA}" />

(Above, we just picked all the apparently PostScript or PDF-related formats that our installation listed as having “read support”.)

A better solution, using an opt-in approach rather than opt-out to reduce your attack surface as much as possible, is something like this:

   <policy domain="coder" rights="none" pattern="*" />
   <policy domain="coder" rights="read|write" pattern="{GIF,JPEG,PNG}" />

The transcoder identification pattern "*" on the first line is a wildcard, meaning it matches anything and therefore turns off everything.

The second line then explicitly turns back on a minimum set of transcoders, based on the file formats you need to support for untrusted uploads.

What next?

If you’re using Linux, or a package manager such as Macports, Homebrew or Fink on a Mac, your system should alert you when an official Ghostscript update is available, so keep your eyes open.