Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Mon, 9 May 2016 08:29:40 -0500 (CDT)
From: Bob Friesenhahn <bfriesen@...ple.dallas.tx.us>
To: oss-security@...ts.openwall.com
Subject: GraphicsMagick Response To "ImageTragick"

[ This is a re-post of what was sent to the GM announcements list ]

This the GraphicsMagick project response to the unfortunate list of
ImageMagick exploits listed on the web site at
https://imagetragick.com/.  While GraphicsMagick forked from
ImageMagick in 2002, it is reasonable to expect that much of the
internal operation and architecture is still similar.  In fact, some
of the claimed exploits (or similar) are relevant to GraphicsMagick.

Based on the current issues described, this is how GraphicsMagick
fares:

1. CVE-2016-3714 - Insufficient shell characters filtering

    GraphicsMagick is not susceptible to remote code execution except
    if gnuplot is installed (because gnuplot executes shell commands).
    Gnuplot-shell based shell exploits are possible without a gnuplot
    file being involved although gnuplot invokes the shell.  To fix
    this, the "gplt" entry in the delegates.mgk file must be removed.

2. CVE-2016-3718 - SSRF

    GraphicsMagick has always supported HTTP and FTP URL requests from
    the context of the executing process if it is linked with libxml2.
    There is no sandboxing or policy to determine which HTTP and FTP
    URLs should be allowed/denied because they should only be available
    from outside the system, or in the public space outside
    a "firewall".

3. CVE-2016-3715 - File deletion

    While the syntax is different from ImageMagick, GraphicsMagick does
    support a file specification syntax "tmp:" which causes the input
    file to be deleted after it is read.  This has limited use to hand
    off responsibility for a temporary file to another process in order
    to assure that the temporary file will be deleted once it is no
    longer needed.  This feature will removed since it is not actually
    necessary any more.

4. CVE-2016-3716 - File moving

     This is a two-factor attack and is actually file copying.  It is
     not successful using GraphicsMagick.  MSL is an XML-based "script"
     format which should never be allowed to be submitted and invoked
     by an untrusted party.

5. CVE-2016-3717 - Local file read

     GraphicsMagick supports a "txt:" file specification syntax which
     enables rendering all the lines of a text file as an image.  There
     is also a "label:" file specification syntax which is capable of
     rendering only the first line of a file.  Files ending with
     extension ".txt" are automatically rendered into an image.  The
     main concern with this is that sensitive data in a text file might
     become rendered as an image on a web site.

     Using an uploaded manual page with file extension ".man" or by
     reading with "man:filename", the 'man' delegate can be used to
     render any file on the system into Postscript if 'groff' is
     installed.

To resolve these concerns, several patches which should apply across
most GraphicsMagick 1.3.XX releases have been developed and are
attached:

1. Remove automatic detection/execution of MVG based on file header or
    file extension. [disable-mvg-ext.patch]

2. Remove the ability to cause an input file to be deleted based on a
    filename specification. [disable-tmp-magick-prefix.patch]

3. Improve the safety of delegates.mgk by removing gnuplot support,
    removing manual page support, and by adding -dSAFER to all
    ghostscript invocations. [delegates-safer.patch]

4. Sanity check the MVG image primitive filename argument to assure
    that "magick:" prefix strings will not be interpreted.  Please note
    that this patch will break intentional uses of magick prefix
    strings in MVG and so some MVG scripts may fail.  We will search
    for a more flexible solution. [image-sanity-check.patch]

Please address any concerns to me (Bob Friesenhahn
<bfriesen@...ple.dallas.tx.us>).

-- 
Bob Friesenhahn
bfriesen@...ple.dallas.tx.us, http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer,    http://www.GraphicsMagick.org/
diff -r 33200fc645f6 config/delegates.mgk.in
--- a/config/delegates.mgk.in	Sat Nov 07 14:49:16 2015 -0600
+++ b/config/delegates.mgk.in	Sun May 08 18:23:04 2016 -0500
@@ -78,28 +78,27 @@
   <delegate decode="dvi" command='"@...DecodeDelegate@" -q -o "%o" "%i"' />
   <delegate decode="edit" stealth="True" command='"@...torDelegate@" -title "Edit Image Comment" -e vi "%o"' />
   <delegate decode="emf" command='"@...DecodeDelegate@" -o "%o" "%i"' />
-  <delegate decode="eps" encode="pdf" mode="bi" command='"@...elegate@" -q -dBATCH -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@...DFDevice@ "-sOutputFile=%o" -- "%i" -c quit' />
-  <delegate decode="eps" encode="ps" mode="bi" command='"@...elegate@" -q -dBATCH -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@...SDevice@ "-sOutputFile=%o" -- "%i" -c quit' />
+  <delegate decode="eps" encode="pdf" mode="bi" command='"@...elegate@" -q -dBATCH -dSAFER -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@...DFDevice@ "-sOutputFile=%o" -- "%i" -c quit' />
+  <delegate decode="eps" encode="ps" mode="bi" command='"@...elegate@" -q -dBATCH -dSAFER -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@...SDevice@ "-sOutputFile=%o" -- "%i" -c quit' />
   <delegate decode="fig" command='"@...DecodeDelegate@" -L ps "%i" "%o"' />
-  <delegate decode="gplt" command='"@...oDelegate@" "set size 1.25,0.62; set terminal postscript portrait color solid; set output \"%o\"; load \"%i\"" > "%u"; "@...plotDecodeDelegate@" "%u"' />
 
   <!-- Read monochrome Postscript, EPS, and PDF  -->
-  <delegate decode="gs-mono" stealth="True" command='"@...elegate@" -q -dBATCH -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@...onoDevice@ -dTextAlphaBits=%u -dGraphicsAlphaBits=%u -r%s %s "-sOutputFile=%s" -- "%s" -c quit' />
+  <delegate decode="gs-mono" stealth="True" command='"@...elegate@" -q -dBATCH -dSAFER -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@...onoDevice@ -dTextAlphaBits=%u -dGraphicsAlphaBits=%u -r%s %s "-sOutputFile=%s" -- "%s" -c quit' />
 
   <!-- Read grayscale Postscript, EPS, and PDF  -->
-  <delegate decode="gs-gray" stealth="True" command='"@...elegate@" -q -dBATCH -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@...rayDevice@ -dTextAlphaBits=%u -dGraphicsAlphaBits=%u -r%s %s "-sOutputFile=%s" -- "%s" -c quit' />
+  <delegate decode="gs-gray" stealth="True" command='"@...elegate@" -q -dBATCH -dSAFER -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@...rayDevice@ -dTextAlphaBits=%u -dGraphicsAlphaBits=%u -r%s %s "-sOutputFile=%s" -- "%s" -c quit' />
 
   <!-- Read colormapped Postscript, EPS, and PDF  -->
-  <delegate decode="gs-palette" stealth="True" command='"@...elegate@" -q -dBATCH -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@...aletteDevice@ -dTextAlphaBits=%u -dGraphicsAlphaBits=%u -r%s %s "-sOutputFile=%s" -- "%s" -c quit' />
+  <delegate decode="gs-palette" stealth="True" command='"@...elegate@" -q -dBATCH -dSAFER -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@...aletteDevice@ -dTextAlphaBits=%u -dGraphicsAlphaBits=%u -r%s %s "-sOutputFile=%s" -- "%s" -c quit' />
 
   <!-- Read color Postscript, EPS, and PDF  -->
-  <delegate decode="gs-color" stealth="True" command='"@...elegate@" -q -dBATCH -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@...olorDevice@ -dTextAlphaBits=%u -dGraphicsAlphaBits=%u -r%s %s "-sOutputFile=%s" -- "%s" -c quit' />
+  <delegate decode="gs-color" stealth="True" command='"@...elegate@" -q -dBATCH -dSAFER -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@...olorDevice@ -dTextAlphaBits=%u -dGraphicsAlphaBits=%u -r%s %s "-sOutputFile=%s" -- "%s" -c quit' />
 
   <!-- Read color+alpha Postscript, EPS, and PDF  -->
-  <delegate decode="gs-color+alpha" stealth="True" command='"@...elegate@" -q -dBATCH -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@...olorAlphaDevice@ -dTextAlphaBits=%u -dGraphicsAlphaBits=%u -r%s %s "-sOutputFile=%s" -- "%s" -c quit' />
+  <delegate decode="gs-color+alpha" stealth="True" command='"@...elegate@" -q -dBATCH -dSAFER -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@...olorAlphaDevice@ -dTextAlphaBits=%u -dGraphicsAlphaBits=%u -r%s %s "-sOutputFile=%s" -- "%s" -c quit' />
 
   <!-- Read CMYK Postscript, EPS, and PDF  -->
-  <delegate decode="gs-cmyk" stealth="True" command='"@...elegate@" -q -dBATCH -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@...MYKDevice@ -dTextAlphaBits=%u -dGraphicsAlphaBits=%u -r%s %s "-sOutputFile=%s" -- "%s" -c quit' />
+  <delegate decode="gs-cmyk" stealth="True" command='"@...elegate@" -q -dBATCH -dSAFER -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@...MYKDevice@ -dTextAlphaBits=%u -dGraphicsAlphaBits=%u -r%s %s "-sOutputFile=%s" -- "%s" -c quit' />
 
   <delegate decode="hpg" command='"@...LDecodeDelegate@" -q -m eps -f `basename "%o"` "%i" && mv -f `basename "%o"` "%o"' />
   <delegate decode="hpgl" command='"@...LDecodeDelegate@" -q -m eps -f `basename "%o"` "%i" && mv -f `basename "%o"` "%o"' />
@@ -108,16 +107,14 @@
   <!-- Read HTML file  -->
   <delegate decode="html" command='"@...LDecodeDelegate@" -U -o "%o" "%i"' />
   <delegate decode="ilbm" command='"@...MDecodeDelegate@" "%i" > "%o"' />
-  <!-- Read UNIX manual page  -->
-  <delegate decode="man" command='"@...Delegate@" -man -Tps "%i" > "%o"' />
   <!-- Read MPEG file using mpeg2decode  -->
   <delegate decode="mpeg" command='"@...GDecodeDelegate@" -q -b "%i" -f -o3 "%u%%05d"; @GMDelegate@ convert -temporary "%u*.ppm" "miff:%o" ; rm -f "%u"*.ppm ' />
   <!-- Write MPEG file using mpeg2encode -->
   <delegate encode="mpeg-encode" stealth="True" command='"@...GEncodeDelegate@" "%i" "%o"' />
   <!-- Convert PDF to Encapsulated Poscript using Ghostscript -->
-  <delegate decode="pdf" encode="eps" mode="bi" command='"@...elegate@" -q -dBATCH -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@...PSDevice@ "-sOutputFile=%o" -- "%i" -c quit' />
+  <delegate decode="pdf" encode="eps" mode="bi" command='"@...elegate@" -q -dBATCH -dSAFER -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@...PSDevice@ "-sOutputFile=%o" -- "%i" -c quit' />
   <!-- Convert PDF to Postcript using Ghostscript -->
-  <delegate decode="pdf" encode="ps" mode="bi" command='"@...elegate@" -q -dBATCH -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@...SDevice@ "-sOutputFile=%o" -- "%i" -c quit' />
+  <delegate decode="pdf" encode="ps" mode="bi" command='"@...elegate@" -q -dBATCH -dSAFER -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@...SDevice@ "-sOutputFile=%o" -- "%i" -c quit' />
   <!-- Convert PNM file to ILBM format using ppmtoilbm -->
   <delegate decode="pnm" encode="ilbm" mode="encode" command='"@...MEncodeDelegate@" -24if "%i" > "%o"' />
   <delegate decode="pnm" encode="launch" mode="encode" command='"@...nchDelegate@" "%i"' />
@@ -125,8 +122,8 @@
   <!-- Read Persistance Of Vision file using povray  -->
   <delegate decode="pov" command='@...Delegate@ "+i"%i"" +o"%o" +fn%q +w%w +h%h +a -q9 -kfi"%s" -kff"%n"
     "@...elegate@" convert -adjoin "%o*.png" "%o"' />
-  <delegate decode="ps" encode="eps" mode="bi" command='"@...elegate@" -q -dBATCH -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@...PSDevice@ "-sOutputFile=%o" -- "%i" -c quit' />
-  <delegate decode="ps" encode="pdf" mode="bi" command='"@...elegate@" -q -dBATCH -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@...DFDevice@ "-sOutputFile=%o" -- "%i" -c quit' />
+  <delegate decode="ps" encode="eps" mode="bi" command='"@...elegate@" -q -dBATCH -dSAFER -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@...PSDevice@ "-sOutputFile=%o" -- "%i" -c quit' />
+  <delegate decode="ps" encode="pdf" mode="bi" command='"@...elegate@" -q -dBATCH -dSAFER -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@...DFDevice@ "-sOutputFile=%o" -- "%i" -c quit' />
   <delegate decode="ps" encode="print" mode="encode" command='"@...ntDelegate@" "%i"' />
   <!-- Read Radiance file using ra_ppm -->
   <delegate decode="rad" command='"@...DecodeDelegate@" -g 1.0 "%i" "%o"' />
@@ -141,5 +138,5 @@
   <delegate decode="txt" encode="ps" mode="bi" command='"@...Delegate@" -o "%o" "%i"' />
   <!-- Render WMF file using wmf2eps (fallback in case libwmf not available) -->
   <delegate decode="wmf" command='"@...DecodeDelegate@" -o "%o" "%i"' />
-  <delegate encode="show" stealth="True" command='"@...elegate@" display -immutable -delay 0 -window_group %g -title "%l of %f" "tmp:%o" &' />
+  <delegate encode="show" stealth="True" command='"@...elegate@" display -immutable -delay 0 -window_group %g -title "%l of %f" "%o" &' />
 </delegatemap>

diff -r 33200fc645f6 coders/mvg.c
--- a/coders/mvg.c	Sat Nov 07 14:49:16 2015 -0600
+++ b/coders/mvg.c	Sat May 07 20:11:54 2016 -0500
@@ -234,6 +234,7 @@
   entry->seekable_stream=True;
   entry->description="Magick Vector Graphics";
   entry->module="MVG";
+  entry->extension_treatment=IgnoreExtensionTreatment;
   (void) RegisterMagickInfo(entry);
 }
 .

diff -r 33200fc645f6 magick/image.c
--- a/magick/image.c	Sat Nov 07 14:49:16 2015 -0600
+++ b/magick/image.c	Sat May 07 20:12:57 2016 -0500
@@ -2780,9 +2780,6 @@
               (void) strlcpy(image_info->magick,magic,MaxTextExtent);
               if (LocaleCompare(magic,"TMP") != 0)
                 image_info->affirm=MagickTrue;
-              else
-                /* input file will be automatically removed */
-                image_info->temporary=MagickTrue;
             }
         }
     }

diff -r 33200fc645f6 magick/render.c
--- a/magick/render.c	Sat Nov 07 14:49:16 2015 -0600
+++ b/magick/render.c	Sun May 08 18:21:47 2016 -0500
@@ -4096,6 +4096,24 @@
           &image->exception);
       else
         {
+          /*
+            Sanity check URL/path before passing it to ReadImage()
+
+            This is a temporary fix until suitable flags can be passed
+            to keep SetImageInfo() from doing potentially dangerous
+            magick things.
+          */
+#define VALID_PREFIX(str,url) (LocaleNCompare(str,url,sizeof(str)-1) == 0)
+          if (!VALID_PREFIX("http://", primitive_info->text) &&
+              !VALID_PREFIX("https://", primitive_info->text) &&
+              !VALID_PREFIX("ftp://", primitive_info->text)  &&
+              !(IsAccessibleNoLogging(primitive_info->text))
+              )
+            {
+              ThrowException(&image->exception,FileOpenError,UnableToOpenFile,primitive_info->text);
+              status=MagickFail;
+              break;
+            }
           (void) strlcpy(clone_info->filename,primitive_info->text,
             MaxTextExtent);
           composite_image=ReadImage(clone_info,&image->exception);

Powered by blists - more mailing lists

Your e-mail address:

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Powered by Openwall GNU/*/Linux - Powered by OpenVZ