diff options
| author | jvoisin | 2018-06-06 23:50:25 +0200 |
|---|---|---|
| committer | jvoisin | 2018-06-06 23:50:25 +0200 |
| commit | 6a832a4104f2da3985f605e9bb973591f19d30f7 (patch) | |
| tree | 0b2bd6f0612c0570fae8455698dc5c619898c36d /libmat2/images.py | |
| parent | fa6c06ed8aee4530e79bc47823a3b7ca2197196d (diff) | |
Prevent exiftool-based parameter-injection
Diffstat (limited to 'libmat2/images.py')
| -rw-r--r-- | libmat2/images.py | 39 |
1 files changed, 23 insertions, 16 deletions
diff --git a/libmat2/images.py b/libmat2/images.py index c84952a..e425735 100644 --- a/libmat2/images.py +++ b/libmat2/images.py | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | import subprocess | 1 | import subprocess |
| 2 | import json | 2 | import json |
| 3 | import os | 3 | import os |
| 4 | import shutil | ||
| 5 | import tempfile | ||
| 4 | 6 | ||
| 5 | import cairo | 7 | import cairo |
| 6 | 8 | ||
| @@ -11,7 +13,26 @@ from gi.repository import GdkPixbuf | |||
| 11 | from . import abstract | 13 | from . import abstract |
| 12 | 14 | ||
| 13 | 15 | ||
| 14 | class PNGParser(abstract.AbstractParser): | 16 | class __ImageParser(abstract.AbstractParser): |
| 17 | def get_meta(self): | ||
| 18 | """ There is no way to escape the leading(s) dash(es) of the current | ||
| 19 | self.filename to prevent parameter injections, so we do have to copy it | ||
| 20 | """ | ||
| 21 | fname = self.filename | ||
| 22 | tmpdirname = "" | ||
| 23 | if self.filename.startswith('-'): | ||
| 24 | tmpdirname = tempfile.mkdtemp() | ||
| 25 | fname = os.path.join(tmpdirname, self.filename) | ||
| 26 | shutil.copy(self.filename, fname) | ||
| 27 | out = subprocess.check_output(['/usr/bin/exiftool', '-json', fname]) | ||
| 28 | if self.filename.startswith('-'): | ||
| 29 | shutil.rmtree(tmpdirname) | ||
| 30 | meta = json.loads(out.decode('utf-8'))[0] | ||
| 31 | for key in self.meta_whitelist: | ||
| 32 | meta.pop(key, None) | ||
| 33 | return meta | ||
| 34 | |||
| 35 | class PNGParser(__ImageParser): | ||
| 15 | mimetypes = {'image/png', } | 36 | mimetypes = {'image/png', } |
| 16 | meta_whitelist = {'SourceFile', 'ExifToolVersion', 'FileName', | 37 | meta_whitelist = {'SourceFile', 'ExifToolVersion', 'FileName', |
| 17 | 'Directory', 'FileSize', 'FileModifyDate', | 38 | 'Directory', 'FileSize', 'FileModifyDate', |
| @@ -28,30 +49,16 @@ class PNGParser(abstract.AbstractParser): | |||
| 28 | except MemoryError: | 49 | except MemoryError: |
| 29 | raise ValueError | 50 | raise ValueError |
| 30 | 51 | ||
| 31 | def get_meta(self): | ||
| 32 | out = subprocess.check_output(['/usr/bin/exiftool', '-json', self.filename]) | ||
| 33 | meta = json.loads(out.decode('utf-8'))[0] | ||
| 34 | for key in self.meta_whitelist: | ||
| 35 | meta.pop(key, None) | ||
| 36 | return meta | ||
| 37 | |||
| 38 | def remove_all(self): | 52 | def remove_all(self): |
| 39 | surface = cairo.ImageSurface.create_from_png(self.filename) | 53 | surface = cairo.ImageSurface.create_from_png(self.filename) |
| 40 | surface.write_to_png(self.output_filename) | 54 | surface.write_to_png(self.output_filename) |
| 41 | return True | 55 | return True |
| 42 | 56 | ||
| 43 | 57 | ||
| 44 | class GdkPixbufAbstractParser(abstract.AbstractParser): | 58 | class GdkPixbufAbstractParser(__ImageParser): |
| 45 | """ GdkPixbuf can handle a lot of surfaces, so we're rending images on it, | 59 | """ GdkPixbuf can handle a lot of surfaces, so we're rending images on it, |
| 46 | this has the side-effect of removing metadata completely. | 60 | this has the side-effect of removing metadata completely. |
| 47 | """ | 61 | """ |
| 48 | def get_meta(self): | ||
| 49 | out = subprocess.check_output(['/usr/bin/exiftool', '-json', self.filename]) | ||
| 50 | meta = json.loads(out.decode('utf-8'))[0] | ||
| 51 | for key in self.meta_whitelist: | ||
| 52 | meta.pop(key, None) | ||
| 53 | return meta | ||
| 54 | |||
| 55 | def remove_all(self): | 62 | def remove_all(self): |
| 56 | _, extension = os.path.splitext(self.filename) | 63 | _, extension = os.path.splitext(self.filename) |
| 57 | pixbuf = GdkPixbuf.Pixbuf.new_from_file(self.filename) | 64 | pixbuf = GdkPixbuf.Pixbuf.new_from_file(self.filename) |
