File Storage Security Architecture
Deep dive into how ZCore prevents path traversal, DoS through large files, arbitrary file deletions, and executable MIME spoofing.
File upload endpoints are among the highest-risk attack vectors in web applications. ZCore's LocalStorageProvider and storage validator suite implement deep defense-in-depth mechanisms to protect host servers against remote code execution (RCE), directory traversal, and resource exhaustion attacks.
1. Path Traversal & Arbitrary File Deletion Defense
Attackers frequently craft malicious filenames or folder parameters (e.g., ../../etc/shadow or ..\..\Windows\System32) to escape the upload root directory.
ZCore mitigates this using multi-stage path sanitization:
- Path Normalization & Key Extraction: Normalizes slashes and strips path prefixes via
_extract_keyto produce isolated POSIX storage keys. - Sandbox Boundary Assertion: Resolves system symlinks and relative path operators (
..) and strictly verifies that the resulting destination resides within the root upload path:
# Internal security validation in local.py
normalized_folder = folder.strip("/\\").replace("\\", "/")
ext = StdPath(filename).suffix.lower()
secure_filename = f"{uuid.uuid4().hex}{ext}"
storage_key = f"{normalized_folder}/{secure_filename}" if normalized_folder else secure_filename
physical_path = self._key_to_path(storage_key)
if physical_path is None:
raise AppException("Path traversal attempt detected")Arbitrary Deletion Protection:
This same boundary verification executes inside storage.delete(file_path_or_url). Incoming web URLs or filesystem paths are resolved via _resolve_path, preventing attackers from exploiting delete endpoints to remove arbitrary system configuration files.
2. Magic Byte Verification & Script Firewall
Relying purely on file extensions (.png, .pdf) or client-provided Content-Type headers is completely insecure, as attackers can disguise PHP web shells or executable binaries as images.
ZCore's SafeMimeTypeValidator reads the first 8192 header bytes to evaluate actual file signatures and detect stored XSS / script vectors:
Executable & Stored XSS Injection Firewall
Even before checking legitimate magic bytes, SafeMimeTypeValidator inspects the initial byte sample against binary headers and active script injection patterns:
- Executable Binary Headers: Windows PE (
MZ), Unix Shebang (#!/), and Linux ELF (\x7fELF) binaries. - PHP Script Blocks:
<?php - HTML/JavaScript Injections:
<script,javascript:,vbscript:,data:text/html,<!doctype html,<html - Embedded Vectors & Handlers:
<iframe>,<object>,<embed>,onload=,onerror=,onclick=,xlink:href=javascript:
If any of these signatures are present, ZCore immediately logs a critical security alert and rejects the request.
3. Denial of Service (DoS) & Memory Exhaustion Mitigation
Uploading multi-gigabyte files can saturate disk space and crash server memory. MaxFileSizeValidator calculates byte capacities safely without buffering entire payloads into RAM:
- Native Inspection: Checks Starlette's
file.sizeattribute if available. - Safe Stream Seeking: For chunked multipart streams, it seeks to the end of the byte stream (
file.file.seek(0, 2)), measures the stream position (file.file.tell()), and immediately rewinds to the beginning (file.file.seek(0)). - If the computed size exceeds
max_size_bytes, the upload is rejected before asynchronous disk writes begin.
4. Collision-Resistant Randomized Filenames
To prevent attackers from overwriting existing files or guessing storage locations, LocalStorageProvider ignores original client filenames when storing on disk.
It generates an isolated, 32-character hexadecimal UUID prefix paired with the normalized extension:
# Generates secure filename: "3f9a8b1c4e2d7a9f8c1b2a3d4e5f6a7b.png"
ext = StdPath(filename).suffix.lower()
secure_filename = f"{uuid.uuid4().hex}{ext}"Asynchronous Disk Streaming:
Once validated, files are written asynchronously using aiofiles in 1 MB chunks, keeping the event loop responsive during concurrent uploads, and returning normalized web URLs prefixed with STORAGE_URL_PREFIX.
Testing Infrastructure (ZTestClient)
Explore how ZCore orchestrates IoC sandboxes, savepoint database rollbacks, context mocking, and application lifespans.
CLI & Structured Logging
Deep dive into ZCore's cascading server runner, introspection-based environment scaffolding, and unified structlog observability pipeline.