diff --git a/libmat2/images.py b/libmat2/images.py
index 153a83d3b21c1c8769b2454e614afdbf837cccf9..dd3be534db2699ba8ba59484382878eac8d15b14 100644
--- a/libmat2/images.py
+++ b/libmat2/images.py
@@ -42,6 +42,21 @@ class PNGParser(exiftool.ExiftoolParser):
         return True
 
 
+class GIFParser(exiftool.ExiftoolParser):
+    mimetypes = {'image/gif'}
+    meta_whitelist = {'AnimationIterations', 'BackgroundColor', 'BitsPerPixel',
+                      'ColorResolutionDepth', 'Directory', 'Duration',
+                      'ExifToolVersion', 'FileAccessDate',
+                      'FileInodeChangeDate', 'FileModifyDate', 'FileName',
+                      'FilePermissions', 'FileSize', 'FileType',
+                      'FileTypeExtension', 'FrameCount', 'GIFVersion',
+                      'HasColorMap', 'ImageHeight', 'ImageSize', 'ImageWidth',
+                      'MIMEType', 'Megapixels', 'SourceFile',}
+
+    def remove_all(self) -> bool:
+        return self._lightweight_cleanup()
+
+
 class GdkPixbufAbstractParser(exiftool.ExiftoolParser):
     """ GdkPixbuf can handle a lot of surfaces, so we're rending images on it,
         this has the side-effect of completely removing metadata.
diff --git a/tests/data/dirty.gif b/tests/data/dirty.gif
new file mode 100644
index 0000000000000000000000000000000000000000..217f90998b05386a0a709727d72c5acc018de928
Binary files /dev/null and b/tests/data/dirty.gif differ
diff --git a/tests/test_libmat2.py b/tests/test_libmat2.py
index 9152b2fd373036a8890ea3af145b68fde96c8f75..935428640297460327cc580b545ee88352f53ae2 100644
--- a/tests/test_libmat2.py
+++ b/tests/test_libmat2.py
@@ -171,6 +171,12 @@ class TestGetMeta(unittest.TestCase):
         meta = p.get_meta()
         self.assertEqual(meta['EncodingSettings'], 'Lavf52.103.0')
 
+    def test_gif(self):
+        p, mimetype = parser_factory.get_parser('./tests/data/dirty.gif')
+        self.assertEqual(mimetype, 'image/gif')
+        meta = p.get_meta()
+        self.assertEqual(meta['Comment'], 'this is a test comment')
+
 class TestRemovingThumbnails(unittest.TestCase):
     def test_odt(self):
         shutil.copy('./tests/data/revision.odt', './tests/data/clean.odt')
@@ -572,3 +578,21 @@ class TestCleaning(unittest.TestCase):
         os.remove('./tests/data/clean.wmv')
         os.remove('./tests/data/clean.cleaned.wmv')
         os.remove('./tests/data/clean.cleaned.cleaned.wmv')
+
+    def test_gif(self):
+        shutil.copy('./tests/data/dirty.gif', './tests/data/clean.gif')
+        p = images.GIFParser('./tests/data/clean.gif')
+
+        meta = p.get_meta()
+        self.assertEqual(meta['Comment'], 'this is a test comment')
+
+        ret = p.remove_all()
+        self.assertTrue(ret)
+
+        p = images.GIFParser('./tests/data/clean.cleaned.gif')
+        self.assertNotIn('EncodingSettings', p.get_meta())
+        self.assertTrue(p.remove_all())
+
+        os.remove('./tests/data/clean.gif')
+        os.remove('./tests/data/clean.cleaned.gif')
+        os.remove('./tests/data/clean.cleaned.cleaned.gif')