SafeZipFile module

This checks each file extracted for “..” in the path, and dont go over a file size limit that you set in the constructor.

from zipfile import ZipFile, ZipInfo
import os

class NotSafeFileException(Exception):
    pass


class SafeZipFile(ZipFile):
    def __init__(self, *args, **kwargs):
        self.max_size = kwargs.pop('max_size', None)
        ZipFile.__init__(self, *args, **kwargs)

    def extract(self, member, path=None, pwd=None):
        if not isinstance(member, ZipInfo):
            member = self.getinfo(member)
        if path is None:
            path = os.getcwd()
        self.safety_check(member)
        return self._extract_member(member, path, pwd)

    def safety_check(self, zipinfo):
        """Make sure that the file/dir:
            * Doesn't start with a slash in the path
            * Doesnt have ".." in the path
            * If max_size is passed, make sure the file isnt bigger than that threshhold
        """
        if zipinfo.filename.startswith("/"): raise NotSafeFileException("%s starts with a slash" % tarinfo.path)
        if ".." in zipinfo.filename: raise NotSafeFileException("%s contains '..'" % zipfile.filename)
        if self.max_size and self.max_size < zipinfo.file_size: raise NotSafeFileException("%s is too big" % zipinfo.filename)

One Response to “SafeZipFile module”

  1. Remco Gerlich Says:

    Thank you for this (and the other post about passing a file descriptor), I happen to be writing a Django app that needs to unzip a lot of files over a cifs mount, and I also have problems with some files being extremely large. Perfect fit :-)

Leave a Reply


Copyright © 2018 All Rights Reserved.
No computers were harmed in the 0.238 seconds it took to produce this page.

dmarkey.com