Skip to content
WarHound AI

Application Security

Archive extraction: traversal, symlinks and resource exhaustion

Processing ZIP archives introduces significant risks including path traversal, arbitrary file writes via symlinks, and resource exhaustion. This guide covers safe extraction techniques, testing matrices, and implementation tradeoffs based on OWASP standards.

Observe. Explain. Retest.MAKE EVIDENCE USEFULWARHOUND / FIELD NOTESCONCEPTREVIEW NOTE / ILLUSTRATIVEOBSERVATIONEVIDENCERETESTObserve. Explain. Retest.MAKE EVIDENCE USEFULOBSERVATIONEVIDENCERETESTWARHOUND / CONCEPTUAL ILLUSTRATION
Useful security reviews connect an observation to evidence and a deliberate retest. Conceptual illustration.

The Inherent Risks of Archive Processing

Handling user-supplied archives fundamentally expands an application's attack surface. The OWASP File Upload Cheat Sheet explicitly warns that ZIP files are not recommended because they can contain all types of files, and the attack vectors pertaining to them are numerous. When an application accepts a compressed archive, it assumes the responsibility of validating not just the container, but every embedded entity, directory structure, and metadata attribute.

Unsafe extraction processes often blindly trust the filenames and paths specified within the archive headers. This trust allows attackers to overwrite critical system files, inject configuration files like .htaccess into web directories, or exhaust system resources by forcing the extraction of highly compressed, massive files. Standard file upload defenses, such as checking the extension of the outer ZIP file, provide zero protection against the payload concealed inside.

Secure implementation requires a defense-in-depth approach. Extracting archives must be treated as parsing untrusted input. The application must enforce strict quotas on extracted size, file count, and compression ratios, while strictly validating the destination paths of every entry to ensure they remain within the intended directory boundaries.

Resource Exhaustion and Quota Enforcement

Resource exhaustion attacks, commonly known as ZIP bombs or XML bombs, exploit the compression ratio of archive formats. A tiny archived file can expand to petabytes of data, consuming all available disk space, memory, and CPU during the extraction process. The OWASP File Upload Cheat Sheet notes that file size limits must be considered after file decompression is conducted.

Mitigating this requires enforcing dynamic extraction quotas. Applications must track the total uncompressed bytes written during the extraction process. If the running total exceeds a predefined threshold, the extraction must immediately halt, and partial files must be purged. Additionally, quotas must restrict the maximum number of files extracted to prevent inode exhaustion, and the maximum compression ratio to detect anomalous archives early in the process.

Relying on the uncompressed size declared in the archive header is a fatal implementation flaw. Attackers can easily forge these headers to bypass preliminary checks. Quotas must be enforced against the actual bytes streamed from the decompression algorithm.

Drafted with Gemini and checked for source links, advisory identifiers, structure and unsupported product claims. Examples are synthetic and are not scan results.

Drafted with Gemini and checked for source links, advisory identifiers, structure and unsupported product claims. Examples are synthetic and are not scan results.

Worked Example: Streaming Decompression with Limits

Consider a hypothetical background worker tasked with extracting user-uploaded themes. A naive implementation reads the entire ZIP into memory or iterates through entries without size checks. A secure implementation uses a streaming approach, maintaining stateful counters for extracted bytes and file counts.

During initialization, the worker sets constants: MAX_TOTAL_BYTES equal to 50 megabytes, MAX_FILE_COUNT equal to 1000, and THRESHOLD_RATIO equal to 100. It resolves the absolute canonical path of the target directory.

As the stream processes each entry, it first checks if the file count exceeds MAX_FILE_COUNT. It then reads the entry name, constructs the destination path, canonicalizes it, and verifies it starts with the target directory path. If it contains a symlink, the entry is rejected. While reading the input stream of the entry, a byte counter increments. If the counter exceeds MAX_TOTAL_BYTES, an exception is thrown, halting extraction. This guarantees memory and disk usage remain bounded regardless of the archive's internal structure.

Safe Test Matrix for Archive Uploads

To validate extraction controls without introducing live exploits, engineers should use a synthetic test matrix utilizing benign, deterministic payloads. These tests ensure the quota and boundary logic functions correctly.

Test Case 1 verifies standard upload logic. Upload a standard ZIP containing three text files totaling 10 kilobytes. Expected outcome: Extraction succeeds, files written to target directory.

Test Case 2 targets path traversal. Upload a ZIP where an entry name is explicitly dot-dot-slash-evil.txt. Expected outcome: Extraction immediately denied, error logged, no files written outside the sandbox.

Test Case 3 targets resource exhaustion limits. Upload a ZIP containing a single file of highly compressible zeroes, sized at 51 megabytes uncompressed, when the limit is 50 megabytes. Expected outcome: Extraction terminates precisely when the 50 megabyte threshold is breached, partial extraction is reverted or isolated.

Test Case 4 evaluates symlink handling. Upload a ZIP with a symlink pointing to an absolute path. Expected outcome: Extraction fails or the symlink is safely ignored, depending on the configured policy.

Implementation Tradeoffs and Failure Modes

Strict extraction controls introduce operational tradeoffs. Enforcing a low maximum file count or size limit may disrupt legitimate users uploading complex, business-necessary archives. Organizations must profile normal usage to establish baseline quotas that balance security and functionality.

A common failure mode occurs when applications attempt partial recovery after a quota breach. If an extraction is halted halfway, leaving partial, unvalidated files in the webroot, attackers might still execute a payload. Extractions must be atomic: they should occur in a temporary, isolated directory outside the webroot. Only after successful validation of the entire uncompressed dataset should the files be atomic-moved to their final destination.

Another failure mode is utilizing outdated parsing libraries. The image processor or ZIP library itself handles untrusted input. Using an up-to-date library with restricted formats, resource limits, and sandboxing is critical. Native shell commands like 'unzip' should be avoided, as they are susceptible to command injection if filenames are improperly sanitized.

Sources and Evidence Limits

The guidelines for file upload protection, including the necessity of calculating file size after decompression and the explicit warning against accepting ZIP files due to numerous attack vectors, are sourced from the OWASP File Upload Cheat Sheet.

Evidence Limits: The provided OWASP documentation establishes baseline requirements for mitigating file upload risks but does not dictate specific framework implementations for extraction logic. The synthetic test matrix provided in this article is hypothetical and designed for safe environment testing; it does not represent claims of performed tests on live infrastructure.

This article was prepared on 2026-11-12 with AI assistance for structural organization and technical prose refinement based strictly on the provided references and product capabilities.

Prepared with AI assistance and published by WarHound AI. Check the references and evidence limits in each article.

The WarHoundAI journal

Questions or a factual correction? Get in touch with the article URL and supporting evidence.

Continue reading.

All articles
Application Security

WebSocket authentication and message authorization

Unlike standard HTTP requests, WebSocket connections remain open for persistent bidirectional data exchange, rendering traditional request-based security filters ineffective. Application engineers must implement custom authentication during the initial handshake, continuously manage session validity over long-lived connections, and authorize individual messages independently to prevent hijacking and unauthorized data access.

Read article 6 min read
Database Security

Tenant isolation with PostgreSQL row security

PostgreSQL Row-Level Security (RLS) provides a robust mechanism for enforcing tenant isolation directly at the database layer. By defining permissive and restrictive policies, application engineers can ensure that data access is restricted on a per-user or per-tenant basis prior to application-level filtering. This article details the implementation of these policies, addresses critical race conditions in policy subqueries, and outlines a comprehensive testing matrix to verify isolation boundaries.

Read article 5 min read
Application Security

Secure server-sent events and reconnect handling

Server-Sent Events (SSE) provide a robust mechanism for unidirectional server-to-client streaming over HTTP. However, the protocol's automatic reconnection behavior introduces subtle authorization and state management challenges. This article explores how browsers handle SSE disconnects, how the Last-Event-ID header functions during recovery, and how to securely design SSE endpoints to prevent unauthorized access or state corruption during network interruptions.

Read article 5 min read