twbgc / sunzip

Provide secure unzip against zip bomb :bomb:.
https://pypi.org/project/sunzip/
GNU General Public License v3.0
38 stars 8 forks source link
secure unzip zipbomb

SUNZIP

forthebadge made-with-python


PyPI Wheel Downloads version travis-ci codecov

Introduction

Why are we doing this?

According to Cara Marie, an archive bomb a.k.a. A zip bomb is often employed to disable antivirus software, in order to create an opening for more traditional viruses. In addition, various kinds of pitfalls may occur during decompression.

PyCon Korea-Click Click Boom! Bombs Over Our Minds

Description for decompression pitfalls on zipfile doc

What is zip bomb?

It often appeared as a relatively small size zip file. And the unzipped file will be much larger than the zipped one. This would probably cause a problem when your disk volume or memory is relatively small than the unzipped one.

How do we defense zip bomb?

    1. Check if it's a nested zip file. (i.e. 42.zip)
    2. Check if the compression ratio (Uncompressed Content/Compressed Content)
       is greater than the threshold?
    3. Check if the file format is expected for context.
    4. Upload file size does not exceed the maximum limit.
    1. Check if CPU time is greater than the threshold.
    2. Check if the extracted part in memory is oversized. (memory usage)

How do we set thresholds?

  Defense Layer 1:
    Uncompressed content size:  200 MB (vt)
    Compression ratio:          https://youtu.be/IXkX2ojrKZQ?t=553

  Defense Layer 2:
    CPU time:                   2 seconds(vt)
    Memoery oversized:

  Defense Layer 3:
    Output file size:
    Number of extracted files:

Useful resources

  Bomb Codes
  https://bomb.codes/

  Mitigation Summary
  https://youtu.be/IXkX2ojrKZQ?t=1296

  Defense layers
  https://bomb.codes/mitigations

Install

$ pip3 install sunzip
# for development use "development mode"
# https://packaging.python.org/tutorials/installing-packages/
$ pip3 install -e <directory to project root>

Usage

# for command line usage see the help
$ sunzip-cli -h

You can find the arguments defined at the top of cli.py

import sunzip

f = sunzip.Sunzip("archive.zip")

Customize your resource limit.

Maximum compression ratio threshold

f.threshold = 50

Maximum CPU time (second)

f.cpu = 1

Maximum memory usage (byte)

f.memory = 1024

Maximum file size (byte)

f.filesize = 1024

If there is no setting, the default value will be used.

extract() would perform a series of the above checks before decompression. If all pass, the zip file will be decompressed.

import sunzip

f = sunzip.Sunzip("archive.zip")

f.extract()