[HN Gopher] A better zip bomb (2019)
___________________________________________________________________
A better zip bomb (2019)
Author : kekqqq
Score : 172 points
Date : 2025-12-19 21:34 UTC (1 days ago)
(HTM) web link (www.bamsoftware.com)
(TXT) w3m dump (www.bamsoftware.com)
| kleiba wrote:
| In one of my previous jobs, I got laid off in the most
| condescending way, only to be asked days later by my former boss
| to send her some documents. If only I knew about this then...
| colechristensen wrote:
| Don't commit felonies because you're unhappy with your former
| employer.
| lossyalgo wrote:
| Is it a felony to crash someone's computer?
| colechristensen wrote:
| Possibly, yes.
| fragmede wrote:
| Violations of the Computer Fraud and Abuse Act (CFAA) can
| be either misdemeanors or felonies. It's definitely broad
| enough that doing so could get you in serious trouble if
| pursued.
| drob518 wrote:
| If done deliberately...
| dpifke wrote:
| If it causes more than $5k in damage. Otherwise, it's a
| misdemeanor.
|
| But you probably don't want to be investigated for either.
| colechristensen wrote:
| A deliberate act of revenge against a former employer...
| wouldn't be given much benefit of the doubt by the
| courts.
| jclarkcom wrote:
| Would it even crash a computer? They would fill up their
| hard drive but that would just yield warnings to the user
| in most operating systems. Chances are they would kill it
| manually because it would take a long time
| tjpnz wrote:
| Nothing wrong with getting some satisfaction. Just don't do
| it in a way that can be traced back to you.
| Computer0 wrote:
| You have bigger enemies more worthy of that personal risk. This
| comment bewilders me a bit.
| cuechan wrote:
| Is it possible to implement something similar but with a protocol
| that supports compression? Can we have a zip bomb but with a
| compressed http response that gets decompressed on the client?
| There are many protocols that support compression in some way.
| dontdoxxme wrote:
| Previously: I use zip bombs to protect my server (idiallo.com)
| 1076 points https://news.ycombinator.com/item?id=43826798
| moreati wrote:
| There was https://idiallo.com/blog/zipbomb-protection earlier
| this year. It sends highly compressed output of /dev/zero. No
| overlapping files or recursively compressed payloads.
| 542458 wrote:
| Okay, so I know back in the day you could choke scanning software
| (ie email attachment scanners) by throwing a zip bomb into them.
| I believe the software has gotten smarter these days so it won't
| simply crash when that happens - but how is this done; How does
| one detect a zip bomb?
| danudey wrote:
| I don't understand the code itself, but here's Debian's patch
| to detect overlapping zip bombs in `unzip`:
|
| https://sources.debian.org/patches/unzip/6.0-29/23-cve-2019-...
| The detection maintains a list of covered spans of the zip
| files so far, where the central directory to the end of
| the file and any bytes preceding the first entry at zip
| file offset zero are considered covered initially. Then
| as each entry is decompressed or tested, it is
| considered covered. When a new entry is about to be
| processed, its initial offset is checked to see if it is
| contained by a covered span. If so, the zip file is rejected as
| invalid.
|
| So effectively it seems as though it just keeps track of which
| parts of the zip file have already been 'used', and if a new
| entry in the zip file starts in a 'used' section then it fails.
| necovek wrote:
| I wonder if this has actually been used for backing up in
| real use cases (think how LVM or ZFS do snapshotting)?
|
| I.e. an advanced compressor could abuse the zip file format
| to share base data for files which only incrementally change
| (get appended to, for instance).
|
| And then this patch would disallow such practice.
| 10000truths wrote:
| For any compression algorithm in general, you keep track of A =
| {uncompressed bytes processed} and B = {compressed bytes
| processed} while decompressing, and bail out when either of the
| following occur:
|
| 1. A exceeds some unreasonable threshold
|
| 2. A/B exceeds some unreasonable threshold
| nrhrjrjrjtntbt wrote:
| Embarrsingly simple for a scanner too as you just mark as
| suspicious when this happens. You can be wrong sometimes and
| this is expected
| integralid wrote:
| In practice one of the things that happens very often is that
| you compress a file filled with null bytes. Such files
| compress extremely well, and would trigger your A/B
| threshold.
|
| On the other hand, zip bomb described in this blog post
| relies on decompressing the same data multiple times - so it
| wouldn't trigger your A/B heuristics necessarily.
|
| Finally, A just means "you can't compress more than X bytes
| with my file format", right? Not a desirable property to
| have. If deflate authors had this idea when they designed the
| algorithm, I bet files larger than "unreasonable" 16MB would
| be forbidden.
| 10000truths wrote:
| > In practice one of the things that happens very often is
| that you compress a file filled with null bytes. Such files
| compress extremely well, and would trigger your A/B
| threshold.
|
| Sure, if you expect to decompress files with high
| compression ratios, then you'll want to adjust your knobs
| accordingly.
|
| > On the other hand, zip bomb described in this blog post
| relies on decompressing the same data multiple times - so
| it wouldn't trigger your A/B heuristics necessarily.
|
| If you decompress the same data multiple times, then you
| increment A multiple times. The accounting still works
| regardless of whether the data is same or different.
| Perhaps a better description of A and B in my post would be
| {number of decompressed bytes written} and {number of
| compressed bytes read}, respectively.
|
| > Finally, A just means "you can't compress more than X
| bytes with my file format", right? Not a desirable property
| to have. If deflate authors had this idea when they
| designed the algorithm, I bet files larger than
| "unreasonable" 16MB would be forbidden.
|
| The limitation is imposed by the application, not by the
| codec itself. The application doing the decompression is
| supposed to process the input incrementally (in the case of
| DEFLATE, reading one block at a time and inflating it),
| updating A and B on each iteration, and aborting if a
| threshold is violated.
| danudey wrote:
| Debian's `unzip` utility, which is based off of Info-ZIP but with
| a number of patches, errors out on overlapping files, though not
| before making a 21 MB file named `0` - presumably the only non-
| overlapping file. unzip zbsm.zip
| Archive: zbsm.zip inflating: 0 error: invalid
| zip file with overlapped components (possible zip bomb)
|
| This seems to have been done in a patch to address
| https://nvd.nist.gov/vuln/detail/cve-2019-13232
|
| https://sources.debian.org/patches/unzip/6.0-29/23-cve-2019-...
| layer8 wrote:
| Yep, these kinds of format shenanigans are increasingly
| rejected for security reasons. Not zip bombs specifically, but
| to prevent parser mismatch vulnerabilities (i.e. two parser
| implementations decompressing the same zip file to different
| contents, without reporting an error).
| Retr0id wrote:
| I think these mitigations are misguided and I've had false-
| positives at least once. Rather than caring about structural
| details (overlapping files etc.), decompressors should just
| limit the overall decompression ratio by default (bytes in vs
| bytes out). It shouldn't matter _how_ the ratio is achieved.
| chupasaurus wrote:
| (2019) with last update in 2023.
| dang wrote:
| Added. Thanks!
| arjie wrote:
| The fact that ZIP files include the catalog/directory at the end
| is such nostalgia fever. Back in the day it meant that if you
| naively downloaded the file, a partial download would be totally
| useless. Fortunately, in the early 2000s, we got HTTP's Range and
| a bunch of zip-aware downloaders that would fetch the catalog
| first so that you could preview a zip you were downloading and
| even extract part of a file! Good times. Well, not as good as
| now, but amusing to think of today.
| st_goliath wrote:
| > ... a partial download would be totally useless ...
|
| no, not _totally_. The directory at the end of the archive
| points backwards to local headers, which in turn include all
| the necessary information, e.g. the compressed size inside the
| archive, compression method, _the filename_ and even a
| checksum.
|
| If the archive isn't some recursive/polyglot nonsense as in the
| article, it's essentially just a tightly packed list of
| compressed blobs, each with a neat, local header in front (that
| even includes a magic number!), the directory at the end is
| really just for quick access.
|
| If your extraction program supports it (or you are sufficiently
| motivated to cobble together a small C program with zlib....),
| you can salvage what you have by linearly scanning and
| extracting the archive, somewhat like a fancy tarball.
| nwallin wrote:
| At work, our daily build (actually 4x per day) is a handful
| of zip files totaling some 7GB. The script to get the build
| would copy the archives over the network, then decompress
| then into your install directory.
|
| This works great on campus, but when everyone went remote
| during COVID it wasn't anymore. It went from three minutes to
| like twenty minutes.
|
| However. Most files change only rarely. I don't need all the
| files, just the ones which are different. So I wrote a
| scanner thing which compares the zip file's filesize and
| checksum to the checksum of the local file. If they're the
| same, we skip it, otherwise, we decompress out of the zip
| file. This cut the time to get the daily build from 20
| minutes to 4 minutes.
|
| Obviously this isn't resilient to an attacker, crc32 is not
| secure, but as an internal tool it's awesome.
| btilly wrote:
| How would this have compared to using rsync?
| necovek wrote:
| Not as much geek cred for using an off the shelf
| solution? ;)
| tonyedgecombe wrote:
| XPS (Microsoft's alternative to PDF) supported this. XPS
| files were ZIP files under the hood and were handled directly
| by some printers. The problem was the printer never had
| enough memory to hold a large file so you had to structure
| the document in a way it could be read a page at a time from
| the start.
| brabel wrote:
| > the directory at the end is really just for quick access.
|
| No, its purpose was to allow multi floppy disks archives. You
| would insert the last disk, then the other ones, one by
| one...
| st_goliath wrote:
| That _literally is_ quick access, it does the same thing in
| both cases, trying to get rid of the linear scan and having
| to plow through data unnecessarily.
|
| If the archive is on a hard disk, the program reads the
| directory at the end and then seeks to the local header,
| rather than doing a linear scan. Or the floppy motor, if it
| is a small archive on a single floppy.
|
| If you have multiple floppies, you insert the last one, the
| program reads the header and then tells you what floppy to
| insert, rather than having to go through them one by one,
| which you know, would be _slower_.
|
| In one case, a hard disk arm, or the floppy motor, does the
| seeking, in the other case, your hands do the seeking. But
| it's still the same algorithm, doing the same thing, for
| the same reason.
| Karliss wrote:
| Partial zip shouldn't be totally useless and a good unzip tool
| should be able to repair such partial downloads. In addition to
| catalog at end zip also have local headers before each file
| entry. So unless you are dealing with maliciously crafted zip
| file or zip file combined with something else, parsing it from
| start should produce identical result. Some zip parsers even
| default to sequential parsing behavior.
|
| This redundant information has lead to multiple vulnerabilities
| over the years. As having redundant information means that a
| maliciously crafted zip file with conflicting headers can have
| 2 different interpretations when processed by 2 different
| parsers.
| cat_plus_plus wrote:
| Well what do you want it to do, it doesn't know full directory
| with offsets until it's done compressing and dispersed
| directory would have lousy access pattern for quick listing.
| And you know, if you are compressing you probably want the
| smallest file so duplicate directories are not idea.
| EvanAnderson wrote:
| Partial downloads weren't useless, though, as other commenters
| have said.
|
| The PKZIP tools came with PKZIPFIX.EXE, which would scan the
| file from the beginning and rebuild a missing central archive.
| You could extract any files up to the truncated file where your
| download stopped.
| halapro wrote:
| I hate that the most common video container on the web does
| this too. Most non-"stream-ready" mp4 files lack even the basic
| information such as height/width until the file has completed
| loading.[1] [1]:
| https://forum.videohelp.com/threads/393096-Fixing-Partially-
| Download-MP4-Files
| thunderfork wrote:
| This is also a big issue if you're using mp4 as your
| container for a real-time capture (e.g. livestreaming and
| saving the stream to disk) - if the capture software crashes
| without writing the MOOV atom, it's a real pain to recover
| the video
| Twirrim wrote:
| Previously discussed in 2019,
| https://news.ycombinator.com/item?id=20352439
|
| Someone shared a link to that site in a conversation earlier this
| year on HN. For a long time now, I've had a gzip bomb sitting on
| my server that I provide to people that make a certain categories
| of malicious calls, such as attempts to log in to wordpress, on a
| site not using wordpress. That post got me thinking about
| alternative types of bombs, particularly as newer compression
| standards have become ubiquitous, and supported in browsers and
| http clients.
|
| I spent some time experimenting with brotli as a compression bomb
| to serve to malicious actors:
| https://paulgraydon.co.uk/posts/2025-07-28-compression-bomb/
|
| Unfortunately, as best as I can see, malicious actors are all
| using clients that only accept gzip, rather than brotli'd
| contents, and I'm the only one to have ever triggered the bomb
| when I was doing the initial setup!
| measurablefunc wrote:
| Decompression is equivalent to executing code for a specialized
| virtual machine. It should be possible to automate this process
| of finding "small" programs that generate "large" outputs. Could
| even be an interesting AI benchmark.
| bikeshaving wrote:
| My guess is this is a subset of the halting problem (does this
| program accept data with non-halting decompression), and is
| therefore beautifully undecidable. You are free to leave
| zip/tgz/whatever fork bombs as little mines for live-off-the-
| land advanced persistent threats in your filesystems.
| machinationu wrote:
| it's not. decompression always ends since it progresses
| through the stream always moving forward. but it might take a
| while
| shakna wrote:
| Many of them already do this. [0]
|
| It is a much easier problem to solve than you would expect. No
| need to drag in a data centre when heuristics can get you close
| enough.
|
| [0]
| https://sources.debian.org/patches/unzip/6.0-29/23-cve-2019-...
| measurablefunc wrote:
| I meant it should be possible to take a specialized virtual
| machine that is equivalent to decompressing some compressed
| bitstream & figure out how to write programs for it that are
| small but generate large outputs, not that it should be
| possible to do static analysis & figure out whether the given
| small program will generate a large output although that is
| also an interesting problem to solve & would also be an
| interesting AI benchmark.
| est wrote:
| I wonder if there's any _reverse_ zip-bombs? e.g. A realy big
| .zip file, takes long time to unzip, but get only few bytes of
| content.
|
| Like bomb the CPU time instead of memory.
| zipping1549 wrote:
| Isn't that mathematically impossible?
| hdjrudni wrote:
| Why's that? I'm not really sure how DEFLATE works but I can
| imagine a crappy compression that's like "5 0" means "00000".
| So if you try to compress "0" you get "1 0" which is longer
| than the input. In fact, I bet this is true for any well-
| compressed format. Like zipping a JpegXL image will probably
| yield something larger. Much larger.. I don't know how you do
| that.
| hayley-patton wrote:
| I'm pretty sure it's mathematically guaranteed that you have
| to be bad at compressing _something_. You can 't compress
| data to less than its entropy, so compressing totally random
| bytes (where entropy = size) would have a high probability of
| not compressing at all, if no identifiable patterns appear in
| the data by sheer coincidence. Establishing then that you
| have incompressible data, the least bad option would be to
| signal to the decompressor to reproduce the data verbatim,
| without any compression. The compressor would increase the
| size of the data by including that signal somehow. Therefore
| there is always some input for a compressor that causes it to
| produce a larger output, even by some miniscule amount.
| nwallin wrote:
| Trivially. Zip file headers specify where the data is. All
| other bytes are ignored.
|
| That's how self extraction archives and installers work and are
| also valid zip files. The extractor part is just a regular
| executable that is a zip decompresser that decompresses itself.
|
| This is specific to zip files, not the deflate algorithm.
| ks2048 wrote:
| That would be a big zip file, but would not take a long time
| to unzip.
| Retr0id wrote:
| There are also deflate-specific tricks you can use - just
| spam empty non-final blocks ad infinitum.
| import zlib zlib.decompress(b"\x00\x00\x00\xff\xff" *
| 1000 + b"\x03\x00", wbits=-15)
|
| If you want to spin more CPU, you'd probably want to define
| random huffman trees and then never use them.
| Retr0id wrote:
| I had claude implement the random-huffman-trees strategy
| and it works alright (~20MB/s decompression speed), but a
| minimal huffman tree that only encodes the end symbol works
| out even slower (~10MB/s), presumably because each tree is
| more compact.
|
| The minimal version boils down to:
| bytes.fromhex("04c001090000008020ffaf96") * 1000000 +
| b"\x03\x00"
| dang wrote:
| Related. Others?
|
| _A better zip bomb [WOOT '19 Paper] [pdf]_ -
| https://news.ycombinator.com/item?id=20685588 - Aug 2019 (2
| comments)
|
| _A better zip bomb_ -
| https://news.ycombinator.com/item?id=20352439 - July 2019 (131
| comments)
| NaOH wrote:
| _A valid HTML zip bomb_ -
| https://news.ycombinator.com/item?id=44670319 - July 2025 (37
| comments)
|
| _I use zip bombs to protect my server_ -
| https://news.ycombinator.com/item?id=43826798 - April 2025 (452
| comments)
|
| _How to defend your website with ZIP bombs (2017)_ -
| https://news.ycombinator.com/item?id=38937101 - Jan 2024 (75
| comments)
|
| _The Most Clever 'Zip Bomb' Ever Made Explodes a 46MB File to
| 4.5 Petabytes_ - https://news.ycombinator.com/item?id=20410681
| - July 2019 (5 comments)
|
| _Defending a website with Zip bombs_ -
| https://news.ycombinator.com/item?id=14707674 - July 2017 (183
| comments)
|
| _Zip Bomb_ - https://news.ycombinator.com/item?id=4616081 -
| Oct 2012 (108 comments)
| RGamma wrote:
| From the bottom of the page
|
| > A final plea
|
| It's time to put an end to Facebook. Working there is not
| ethically neutral: every day that you go into work, you are doing
| something wrong. If you have a Facebook account, delete it. If
| you work at Facebook, quit.
|
| And let us not forget that the National Security Agency must be
| destroyed.
___________________________________________________________________
(page generated 2025-12-20 23:02 UTC)