Arbitrary local file read via file upload
Description
This vulnerability allows attackers to read arbitrary local files from the web server by uploading a specially crafted ZIP archive containing symbolic links (symlinks). When the application extracts and processes the ZIP file, it follows the symlink and exposes the contents of sensitive system files, such as /etc/passwd. This occurs because the application fails to validate or sanitize symlinks within uploaded archives before processing them.
Remediation
Implement proper validation and sanitization of ZIP file contents before extraction. Specifically:
1. Detect and reject symlinks: Before extracting files, inspect each entry in the ZIP archive and reject any that are symbolic links.
2. Use secure extraction methods: Utilize libraries or functions that provide options to ignore or reject symlinks during extraction.
3. Validate extracted file paths: Ensure all extracted files remain within the intended directory using path canonicalization and validation.
Example (Python):
import zipfile
import os
def safe_extract(zip_path, extract_to):
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
for member in zip_ref.namelist():
# Get file info
info = zip_ref.getinfo(member)
# Check if file is a symlink (external_attr indicates file type)
if info.external_attr >> 16 == 0o120000:
raise ValueError(f"Symlink detected: {member}")
# Validate path to prevent directory traversal
target_path = os.path.join(extract_to, member)
if not os.path.abspath(target_path).startswith(os.path.abspath(extract_to)):
raise ValueError(f"Invalid path: {member}")
zip_ref.extract(member, extract_to)
4. Apply principle of least privilege: Run the web application with minimal file system permissions to limit exposure if exploitation occurs.