• Stars
    star
    255
  • Rank 159,729 (Top 4 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 5 years ago
  • Updated over 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Robust ZIP decoder with defenses against dangerous compression ratios, spec deviations, malicious archive signatures, mismatching local and central directory headers, ambiguous UTF-8 filenames, directory and symlink traversals, invalid MS-DOS dates, overlapping headers, overflow, underflow, sparseness, accidental buffer bleeds etc.

zip

Robust ZIP decoder with defenses against dangerous compression ratios, spec deviations, malicious archive signatures, mismatching local and central directory headers, ambiguous UTF-8 filenames, directory and symlink traversals, invalid MS-DOS dates, overlapping headers, overflow, underflow, sparseness, buffer bleeds etc.

Installation

npm install @ronomon/zip

Usage

Inspect the local file headers of an archive at the command line:

scripts/decode <file>

Parse the local file headers of an archive:

var ZIP = require('@ronomon/zip');
var buffer = fs.readFileSync(archive);
try {
  var headers = ZIP.decode(buffer);
} catch (error) {
  console.error(error.message);
}

Extract the file data of a local file header:

var file = ZIP.inflate(header, buffer);

Robust

  • Rejects zip files that are too small, i.e. less than 22 bytes.

  • Rejects zip files that exceed 2 GB to protect vulnerable downstream zip implementations from int32_t overflow.

  • Rejects zip files that are truncated, i.e. with no end of central directory record.

  • Rejects zip files with prepended data, which can be exploited to distribute malicious JAR files appended to MSI files signed by third parties and other chameleon files. A chameleon file is an ambiguous file that looks different depending on the parser implementation used to open the file.

  • Rejects zip files with appended data, which can be exploited for malware stuffing or which might represent buffer bleeds.

  • Rejects zip files with dangerous compression ratios, i.e. more than 100 to 1. These are unlikely to be benign.

  • Rejects zip files with excessively negative compression ratios (CVE-2018-18384).

  • Rejects malicious rar, tar and xar files that pretend to be zip files in order to evade content type detection or antivirus scanning. Some unzip utilities will unzip these files.

  • Rejects local file headers that overlap, which can be exploited for zip bombs.

  • Rejects local file headers that diverge from the central directory header, which can be exploited to create ambiguity in file metadata or content. For example, some decoders might interpret the local file header as a malicious EXE file, while most decoders might interpret the central directory header as a harmless TXT file.

  • Rejects local file headers that overflow each other or the central directory, which can be exploited for remote code execution.

  • Rejects local file headers that underflow each other or the central directory, i.e. gaps between local files or between the last local file and the central directory, which might be exploited for malware stuffing or which might represent buffer bleeds.

  • Rejects local file headers with invalid combinations of bit 3, crc32 and compressed or uncompressed sizes. Malware hygiene is poor when it comes to the spec.

  • Rejects data descriptors that overflow.

  • Rejects central directory headers that overflow.

  • Rejects central directory headers that underflow.

  • Rejects archives spanning multiple disks, encryption mechanisms and archive headers, compression methods other than 0 (uncompressed) or 8 (deflate), ZIP64 version 2 (and ZIP64 version 1), unused and reserved flags, since all of these are rejected by ISO/IEC 21320-1:2015. Encrypted archives are often used to distribute malware and evade antivirus scanning.

  • Rejects compression methods greater than 999 to prevent buffer overflows (CVE-2016-9844).

  • Accepts UTF-8 as well as the CP437 character encoding contrary to ISO/IEC 21320-1:2015 since CP437 is a common zip character encoding.

  • Rejects unequal compressed and uncompressed sizes when a file is stored uncompressed, which can be exploited to create ambiguity, i.e. in file content.

  • Rejects MS-DOS date years after 2099 that are not correctly handled by some zip implementations.

  • Rejects MS-DOS date months that are out of range, i.e. more than 12, characteristic of malware archives.

  • Rejects MS-DOS date days that are out of range, i.e. more than 31, characteristic of malware archives.

  • Rejects MS-DOS date hours that are out of range, i.e. more than 23, characteristic of malware archives.

  • Rejects MS-DOS date minutes that are out of range, i.e. more than 59, characteristic of malware archives.

  • Rejects MS-DOS date seconds that are out of range, i.e. more than 59, characteristic of malware archives.

  • Rejects unicode path extra fields that overflow.

  • Rejects unicode path extra fields that underflow.

  • Rejects unicode path extra fields that have an invalid version.

  • Rejects unicode path extra fields that diverge from the central directory, which can be exploited to create ambiguity, i.e. in file extension.

  • Rejects extra fields that exceed 4096 bytes as an arbitrary upper bound.

  • Rejects extra fields with an invalid length, i.e. only 1, 2 or 3 bytes.

  • Rejects invalid UTF-8 strings, which can be used to exploit vulnerable UTF-8 decoders.

  • Rejects directories that pretend to be files, i.e. with compressed or uncompressed sizes not equal to 0.

  • Rejects dangerous unix mode permissions: setuid, setgid and sticky bits (CVE-2005-0602).

  • Rejects dangerous unix mode types: block devices, character devices, fifo special files and sockets.

  • Rejects file names containing null bytes.

  • Rejects file names containing control characters, which can be used to mask ".." as part of a directory traversal (CVE-2003-0282).

  • Rejects file names containing backslashes. All slashes must be forward slashes according to the spec.

  • Rejects file names exceeding 4096 bytes to prevent buffer overflows (CVE-2018-1000035).

  • Rejects file name components exceeding 255 bytes to prevent buffer overflows.

  • Rejects directory traversal via file name, which can be exploited to overwrite system files.

  • Rejects directory traversal via symlink, which can be exploited to overwrite system files. Some zip decoders, including antivirus scanners and popular email services, do not detect directory traversal via symlink.

  • Rejects compressed symlinks for simplicity, since these are highly unlikely.

  • Rejects symlinks that exceed 1024 bytes as an arbitrary upper bound to prevent runaway string decoding.

Tests

@ronomon/zip has been tested on several large and diverse data sets, including David Fifield's "A better zip bomb".

Automated fuzz tests are yet to be included.

More Repositories

1

hash-table

Fast, reliable cuckoo hash table for Node.js.
JavaScript
299
star
2

pure

A static analysis file format checker.
C
233
star
3

crypto-async

Fast, reliable cipher, hash and hmac methods executed in Node's threadpool for multi-core throughput.
JavaScript
174
star
4

reed-solomon

Fast, reliable Reed-Solomon erasure coding as a native addon for Node.js.
JavaScript
104
star
5

deduplication

Fast multi-threaded content-dependent chunking deduplication for Buffers in C++ with a reference implementation in Javascript. Ships with extensive tests, a fuzz test and a benchmark.
JavaScript
69
star
6

direct-io

Direct IO helpers for block devices and regular files on FreeBSD, Linux, macOS and Windows.
C
66
star
7

mime

Fast, robust, standards-compliant MIME decoder. Ships with extensive tests and fuzz tests.
JavaScript
61
star
8

utimes

Change the birth time (`btime`), modified time (`mtime`) and/or access time (`atime`) of a file on Windows, macOS and Linux.
JavaScript
34
star
9

base64

Fast, robust Base64 encoder/decoder for Buffers in C++. Ignores whitespace. Detects corruption and truncation. Ships with extensive tests, a fuzz test and a benchmark.
JavaScript
17
star
10

opened

Check if a file is open in another application on Windows, macOS and Linux.
JavaScript
13
star
11

queue

Process thousands of asynchronous or synchronous jobs, concurrently or sequentially, safely and efficiently, without creating thousands of closures.
JavaScript
9
star
12

quoted-printable

Fast, robust RFC 2045 (Quoted-Printable) and RFC 2047 (Q-Encoding) encoder/decoder for Buffers in pure Javascript with an optional C++ binding. Avoids intermediary string allocations and regular expressions. Reduces branching through the use of lookup tables.
JavaScript
3
star