This is related to the question about zip bombs, but having gzip or bzip2 compression in mind, e.g. a web service accepting .tar.gz
files.
Python provides a handy tarfile module that is convenient to use, but does not seem to provide protection against zipbombs.
In python code using the tarfile module, what would be the most elegant way to detect zip bombs, preferably without duplicating too much logic (e.g. the transparent decompression support) from the tarfile module?
And, just to make it a bit less simple: No real files are involved; the input is a file-like object (provided by the web framework, representing the file a user uploaded).
Deny any compressed files that contain compressed files. Use ZipFile. entries() to retrieve a list of files, then ZipEntry. getName() to find the file extension.
How do you locate a decompression bomb? Most modern antivirus programs can detect zip bombs by looking for overlapping files. They know not to unpack layer after layer of recursive data, which is a sign of a decompression bomb. Often, antivirus software labels a file a decompression bomb when it is not actually a bomb.
The only catch is that the zip bomb contains so much compressed data that unpacking it requires excessively massive amounts of memory, disk space and time. Ultimately, zip bombs are harmful to the system because they make the 'environment' of a computer more conducive for an attack by traditional viruses.
You could use resource
module to limit resources available to your process and its children.
If you need to decompress in memory then you could set resource.RLIMIT_AS
(or RLIMIT_DATA
, RLIMIT_STACK
) e.g., using a context manager to automatically restore it to a previous value:
import contextlib
import resource
@contextlib.contextmanager
def limit(limit, type=resource.RLIMIT_AS):
soft_limit, hard_limit = resource.getrlimit(type)
resource.setrlimit(type, (limit, hard_limit)) # set soft limit
try:
yield
finally:
resource.setrlimit(type, (soft_limit, hard_limit)) # restore
with limit(1 << 30): # 1GB
# do the thing that might try to consume all memory
If the limit is reached; MemoryError
is raised.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With