diff options
author | Simon McVittie <smcv@debian.org> | 2016-05-05 23:17:45 +0100 |
---|---|---|
committer | Simon McVittie <smcv@debian.org> | 2016-05-05 23:43:50 +0100 |
commit | 170cd41489ab25fc3b7a95dd31521dfe522b4f9e (patch) | |
tree | a6ce0d308d7304451ec646c3744e24aff7d8853d /IkiWiki | |
parent | 545a7bbbf07dd2375a96eae09f9abd6329a919e5 (diff) | |
download | ikiwiki-170cd41489ab25fc3b7a95dd31521dfe522b4f9e.tar ikiwiki-170cd41489ab25fc3b7a95dd31521dfe522b4f9e.tar.gz |
img: check magic number before giving common formats to ImageMagick
This mitigates CVE-2016-3714 and similar vulnerabilities by
avoiding passing obviously-wrong input to ImageMagick decoders.
Diffstat (limited to 'IkiWiki')
-rw-r--r-- | IkiWiki/Plugin/img.pm | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/IkiWiki/Plugin/img.pm b/IkiWiki/Plugin/img.pm index 53d963425..ed2e9354d 100644 --- a/IkiWiki/Plugin/img.pm +++ b/IkiWiki/Plugin/img.pm @@ -99,20 +99,29 @@ sub preprocess (@) { # Never interpret well-known file extensions as any other format, # in case the wiki configuration unwisely allows attaching # arbitrary files named *.jpg, etc. + my $magic; + my $offset = 0; + open(my $in, '<', $srcfile) or error sprintf(gettext("failed to read %s: %s"), $file, $!); + binmode($in); + if ($extension =~ m/^(jpeg|jpg)$/is) { $format = 'jpeg'; + $magic = "\377\330\377"; } elsif ($extension =~ m/^(png)$/is) { $format = 'png'; + $magic = "\211PNG\r\n\032\n"; } elsif ($extension =~ m/^(gif)$/is) { $format = 'gif'; + $magic = "GIF8"; } elsif ($extension =~ m/^(svg)$/is) { $format = 'svg'; } elsif ($extension =~ m/^(pdf)$/is) { $format = 'pdf'; + $magic = "%PDF-"; } else { # allow ImageMagick to auto-detect (potentially dangerous) @@ -121,6 +130,25 @@ sub preprocess (@) { error sprintf(gettext("%s image processing disabled in img_allowed_formats configuration"), $format ? $format : "\"$extension\"") unless allowed($format ? $format : "everything"); + # Try harder to protect ImageMagick from itself + if ($format eq 'svg') { + my $content; + read($in, $content, 5) or error sprintf(gettext("failed to read %s: %s"), $file, $!); + # This is an over-simplification, but ?xml is the check that + # ImageMagick uses. We also accept <svg for the simplest + # possible SVGs. + if ($content !~ m/^(.\?xml|<svg)/is) { + error sprintf(gettext("\"%s\" does not seem to be a valid %s file"), $file, $format); + } + } + elsif ($magic) { + my $content; + read($in, $content, length $magic) or error sprintf(gettext("failed to read %s: %s"), $file, $!); + if ($magic ne $content) { + error sprintf(gettext("\"%s\" does not seem to be a valid %s file"), $file, $format); + } + } + my $issvg = $base=~s/\.svg$/.png/i; my $ispdf = $base=~s/\.pdf$/.png/i; my $pagenumber = exists($params{pagenumber}) ? int($params{pagenumber}) : 0; |