SafeTarFile Module

This TarFile module is a drop-in replacement for TarFile which makes sure that files in a tarfile, is safe using the following criteria:

* Doesn’t start with a slash in the path
* Doesnt have “..” in the path
* Is either a normal file or directory(no fifos, symlinks)
* If max_size is passed, make sure the file isnt bigger than that threshhold

Tested on 2.7

from tarfile import TarFile, ExtractError
import copy
import operator
import os.path

class NotSafeFileException(Exception):
    pass

class SafeTarFile(TarFile):
    def __init__(self, *args, **kwargs):
        self.max_size = kwargs.pop('max_size', None)
        super(SafeTarFile,self).__init__(*args, **kwargs)

    def safety_check(self, tarinfo, max_size=None):
        """Make sure that the file/dir:
            * Doesn't start with a slash in the path
            * Doesnt have ".." in the path
            * Is either a normal file or directory(no fifos,  symlinks)
            * If max_size is passed, make sure the file isnt bigger than that threshhold
        """

        if tarinfo.path.startswith("/"): raise NotSafeFileException("%s starts with a slash" % tarinfo.path)
        if ".." in tarinfo.path: raise NotSafeFileException("%s contains '..'" % tarinfo.path)
        if not tarinfo.isfile() and not tarinfo.isdir(): raise NotSafeFileException("%s is a strange filetype" % tarinfo.name)
        if self.max_size and self.max_size < tarinfo.size: raise NotSafeFileException("%s is too big" % tarinfo.name)

    def extract(self, member, path=""):
        self._check("r")

        if isinstance(member, basestring):
            tarinfo = self.getmember(member)
        else:
            tarinfo = member
        self.safety_check(tarinfo)
        super(SafeTarFile, self).extract(tarinfo, path)

Leave a Reply


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

dmarkey.com