summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjvoisin2018-06-06 23:50:25 +0200
committerjvoisin2018-06-06 23:50:25 +0200
commit6a832a4104f2da3985f605e9bb973591f19d30f7 (patch)
tree0b2bd6f0612c0570fae8455698dc5c619898c36d
parentfa6c06ed8aee4530e79bc47823a3b7ca2197196d (diff)
Prevent exiftool-based parameter-injection
-rw-r--r--libmat2/images.py39
-rw-r--r--tests/test_libmat2.py10
2 files changed, 33 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 @@
1import subprocess 1import subprocess
2import json 2import json
3import os 3import os
4import shutil
5import tempfile
4 6
5import cairo 7import cairo
6 8
@@ -11,7 +13,26 @@ from gi.repository import GdkPixbuf
11from . import abstract 13from . import abstract
12 14
13 15
14class PNGParser(abstract.AbstractParser): 16class __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
35class 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
44class GdkPixbufAbstractParser(abstract.AbstractParser): 58class 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)
diff --git a/tests/test_libmat2.py b/tests/test_libmat2.py
index 89a5811..84eb75e 100644
--- a/tests/test_libmat2.py
+++ b/tests/test_libmat2.py
@@ -17,6 +17,16 @@ class TestParserFactory(unittest.TestCase):
17 self.assertEqual(parser.__class__, audio.MP3Parser) 17 self.assertEqual(parser.__class__, audio.MP3Parser)
18 18
19 19
20class TestParameterInjection(unittest.TestCase):
21 def test_ver_injection(self):
22 shutil.copy('./tests/data/dirty.png', './-ver')
23 p = images.PNGParser('-ver')
24 meta = p.get_meta()
25 self.assertEqual(meta['Comment'], 'This is a comment, be careful!')
26 self.assertEqual(meta['ModifyDate'], "2018:03:20 21:59:25")
27 os.remove('-ver')
28
29
20class TestUnsupportedFiles(unittest.TestCase): 30class TestUnsupportedFiles(unittest.TestCase):
21 def test_pdf(self): 31 def test_pdf(self):
22 shutil.copy('./tests/test_libmat2.py', './tests/clean.py') 32 shutil.copy('./tests/test_libmat2.py', './tests/clean.py')