Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Protect JavaScript-created ZIP files by validating every archive entry name before writing it, and by treating extraction as a separate security problem. A safe archive writer cannot make a downstream extractor safe: if your application also opens ZIP files, it must independently prevent path traversal and limit decompression work.

Why ZIP creation and extraction need separate protections

A ZIP file contains filenames as well as compressed data. Those names are security-sensitive metadata: another program may use them as filesystem paths when it extracts the archive. An unsafe name can therefore put the risk on the person or application that later unpacks the file.

Zip Slip describes directory traversal in which an extractor uses an archive filename without adequate validation, allowing a file operation to target a location outside the intended destination. Creating an archive with safe names reduces risk for its recipients, but does not secure your own code if it extracts untrusted archives. See CodeQL’s JavaScript Zip Slip guidance.

Validate entry names before creating the archive

Build archive paths from a constrained naming policy rather than passing user-controlled filesystem paths directly into ZIP metadata. Keep names relative and normalized. Reject absolute paths, drive-qualified paths, NUL bytes, ambiguous separators, and any path containing a .. segment. Normalize separators consistently, and reject unsafe input at the trust boundary instead of silently changing its meaning.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Decide which directory structure your application permits, then generate names within that structure.
  • Check every component, not just the full string prefix: a name containing a traversal segment must not be accepted because it happens to begin with an allowed directory name.
  • Define what happens when names collide after normalization, including duplicate files and case- or separator-related collisions.
  • Check the selected library’s path rules and defaults. The yazl documentation specifies constraints on metadata paths; JSZipp’s API documentation describes strict and sanitize modes for reading and path normalization behavior for writing.

Protect the extraction path if your application opens ZIP files

If your application extracts user-supplied archives, fix the destination directory and verify that each resolved output path remains inside it before writing. Do not assume that a ZIP produced by your own application—or by a trusted sender—will always be safe to extract.

  1. Resolve each archive entry against the fixed extraction destination.
  2. Check that the resulting path is still contained within that destination before creating or writing the file.
  3. Test traversal forms and separator behavior on every operating system your application supports; drive letters and path separators are interpreted differently across platforms.
  4. Reject malformed structures and duplicate or colliding names according to an explicit policy, and avoid leaving partial files in trusted locations if extraction fails.

CodeQL documents the Zip Slip risk in JavaScript, and the Node.js nightly v27 ZIP API documentation is a further reference for ZIP handling. That Node.js documentation describes an experimental API, so its behavior and availability should not be treated as stable across releases.

Limit decompression work when accepting untrusted archives

A small compressed upload can expand into a much larger amount of data. Compressed input length alone does not bound decompression cost, and checking the expanded size only after fully inflating an entry is too late to prevent excessive resource use.

Set limits that fit your application’s workload and resource budget. There is no universal numeric limit established by the cited documentation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Maximum compressed input size.
  • Maximum number of entries and maximum expanded bytes per entry.
  • Maximum total expanded bytes across the archive.
  • Processing time, nesting depth, and nested-archive handling where relevant.

Enforce expanded-size limits while reading or inflating data. JSZipp documents input archive and per-entry decompression caps, with its per-entry cap applied during inflate; consult its API documentation for the available controls. Do not assume every library imposes equivalent limits or checks inconsistent size metadata by default.

Choose a ZIP library for your environment and workload

There is no universally best or safest JavaScript ZIP library established by the available documentation. Compare the supported environments, buffering and streaming behavior, path policy, malformed-archive handling, large-file support, and current maintenance status before adopting one.

Library or API Documented fit What to check
yazl Node.js archive writing with asynchronous, memory-conscious behavior. Confirm its path constraints fit your naming policy and verify current package compatibility and release status.
JSZipp Browser-oriented writer outputs, including Blob, Response, and stream output; reader options document configurable limits. Review current API defaults, strict or sanitize behavior, and the controls available for your specific read or write path.
JSZip A ZIP library whose documentation describes JavaScript integer-precision and memory constraints for large archives. Assess whether your archive sizes and memory budget fit those documented limitations.

For any candidate, check compatibility with the extractors your recipients actually use, ZIP64 and large-file behavior, duplicate-name handling, error and cancellation behavior, and how failed operations affect partial output. Library behavior, defaults, supported platforms, and release status can change, so verify the version you plan to deploy rather than relying on an old example.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Use streaming without mistaking it for a security boundary

Streaming can reduce the need to buffer an entire archive in memory, which is useful for larger inputs or outputs. It does not validate paths, prevent traversal, or impose decompression limits. Keep those controls in place whether the library streams or buffers.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Handle stream errors and cancellation explicitly, enforce limits as data is processed, and ensure failed operations do not leave partial output in a trusted location. The yazl documentation describes asynchronous, memory-conscious Node.js archive writing, while JSZipp documents browser-oriented stream and other output options.

Remember that compression streams are not ZIP containers

The browser’s Compression Streams API supports gzip and deflate streams; it is not a complete ZIP implementation. ZIP files include archive structures beyond compressed data, so use a ZIP-aware library for creating or reading ZIP containers. See MDN’s Compression Streams API documentation.

Keep unrelated web protections in their proper scope

A Content Security Policy can help reduce other web script-injection risks, but it does not validate ZIP entry names or limit decompression resource use. Treat it as a separate application security control, not a substitute for ZIP-specific checks. MDN explains CSP deployment in its practical implementation guidance.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.