Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to protect myself from a gzip or bzip2 bomb?

Tags:

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).

like image 842
Joachim Breitner Avatar asked Nov 29 '12 09:11

Joachim Breitner


People also ask

How do you protect yourself from a zip bomb?

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 know if its a zip bomb?

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.

Do zip bombs still work?

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.


1 Answers

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.

like image 122
jfs Avatar answered Sep 17 '22 15:09

jfs