Zip Slip with Api Keys
How Zip Slip Manifests in Api Keys
Zip Slip in API key management systems typically occurs when untrusted archive files containing API keys are extracted to disk without proper validation. This vulnerability allows attackers to overwrite critical files, including configuration files that store API keys, by crafting malicious ZIP archives with path traversal sequences.
The most common manifestation involves API key extraction workflows. When developers accept ZIP uploads containing API key bundles, configuration files, or deployment packages, insufficient path validation enables attackers to write files outside the intended directory. For example, a malicious ZIP might contain ../../config/api-keys.json which overwrites the application's actual API key storage.
# Vulnerable API key extraction in Python
import zipfile
import os
def extract_api_keys(zip_path, extract_to):
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
zip_ref.extractall(extract_to) # Vulnerable: no path validation
# Malicious ZIP content:
# - ../../config/api-keys.json (overwrites actual API keys)
# - ../../.env (overwrites environment variables)
# - ../../main.py (overwrites application code)Another critical scenario involves API key rotation systems. When services rotate API keys by extracting new key bundles from ZIP archives, Zip Slip can redirect the extraction to system directories. An attacker might craft a ZIP containing /etc/passwd or /usr/local/bin/update-keys, replacing system files when the extraction occurs with elevated privileges.
# Malicious ZIP structure targeting API key systems
$ unzip -l malicious.zip
../../etc/api-keys.json
../../usr/local/bin/rotate-keys
../../var/log/api-access.logCloud storage integrations present additional risks. When API keys are stored in cloud buckets and extracted to local filesystems, Zip Slip can traverse cloud storage paths. A ZIP containing ../../../production/api-keys.json might overwrite production API keys when extracted by a deployment pipeline.
API Keys-Specific Detection
Detecting Zip Slip in API key systems requires both static analysis and runtime scanning. Static analysis examines code paths that handle ZIP extraction, looking for missing path validation before file operations.
# Detection: vulnerable extraction function
import ast
def find_vulnerable_zip_extraction(node):
if isinstance(node, ast.Call):
if (isinstance(node.func, ast.Attribute) and
node.func.attr == 'extractall' and
not has_path_validation(node.parent)):
return True
return False
# middleBrick scanning identifies these patterns automatically
# No configuration required - just submit your API endpointRuntime detection focuses on monitoring file system operations during ZIP processing. Tools should watch for:
- Path traversal sequences (../, ..\, or URL-encoded equivalents)
- Absolute path writes outside designated directories
- Symlink resolution that escapes extraction boundaries
- Device file creation (block devices, character devices)
- Special file types (FIFO, sockets) in unexpected locations
middleBrick's black-box scanning specifically tests for Zip Slip by submitting crafted ZIP archives containing path traversal payloads. The scanner monitors whether these archives can write files outside intended directories, testing the exact attack surface your API exposes.
API key-specific indicators include:
- Extraction of files to directories containing
api-keys,credentials, orconfig - Writing to
.env,config.json, orkeys.yamlfiles - Modification of
package.jsonorrequirements.txtthat might alter dependency resolution
Security headers and configuration files are also targeted. A ZIP containing ../../.htaccess or ../../nginx.conf can redirect API traffic or disable security controls, indirectly compromising API key protection.
API Keys-Specific Remediation
Effective remediation requires multiple layers of defense. The primary defense is path validation before extraction. Modern libraries provide safe extraction methods, but custom validation offers more control.
# Secure API key extraction with path validation
import zipfile
import os
import pathlib
def safe_extract_api_keys(zip_path, extract_to):
extract_to = pathlib.Path(extract_to).resolve()
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
for member in zip_ref.infolist():
# Resolve target path and check if it's within the base directory
target_path = pathlib.Path(member.filename).resolve()
if not str(target_path).startswith(str(extract_to)):
raise ValueError(f"Path traversal attempt: {member.filename}")
# Additional API key-specific checks
if '../' in member.filename or '..\\' in member.filename:
raise ValueError("Relative path traversal detected")
# Check for dangerous file types
if member.filename.startswith('/') or member.filename.startswith('\\'):
raise ValueError("Absolute path detected")
# Block symbolic links that could escape the directory
if member.create_system == 3: # Unix symlink
raise ValueError("Symlink detected in archive")
# Safe extraction after all validation passes
zip_ref.extractall(extract_to)API key management systems should implement content validation. Before extracting any archive, verify that it contains only expected file types and structures.
# API key archive content validation
import json
def validate_api_key_archive(zip_path):
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
namelist = zip_ref.namelist()
# API key bundles should only contain specific files
allowed_files = {
'api-keys.json',
'private-key.pem',
'public-cert.crt',
'config.yaml'
}
for filename in namelist:
if filename not in allowed_files:
raise ValueError(f"Unexpected file in API key archive: {filename}")
# Check file contents for malicious data
if filename.endswith('.json'):
content = zip_ref.read(filename)
try:
data = json.loads(content)
# Validate JSON structure contains only expected keys
if not set(data.keys()).issubset({'api_key', 'secret', 'endpoint'}):
raise ValueError("Unexpected JSON structure")
except json.JSONDecodeError:
raise ValueError("Invalid JSON content")
return TrueRuntime protection adds another layer. Monitor file system operations during extraction and implement allowlists for file modifications.
# Runtime protection for API key directories
import os
import stat
def protect_api_key_directories(base_dir):
# Make API key directories read-only
api_dirs = [
'api-keys',
'config',
'credentials',
'.env'
]
for dir_name in api_dirs:
dir_path = os.path.join(base_dir, dir_name)
if os.path.exists(dir_path):
os.chmod(dir_path, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
# Monitor for unauthorized writes
def monitor_writes(event):
if event.is_write and any(d in event.path for d in api_dirs):
raise PermissionError("Unauthorized write to API key directory")
# Implement file system watcher (pseudo-code)
start_file_watcher(base_dir, monitor_writes)For CI/CD pipelines, implement pre-deployment scanning. Before deploying API key updates, scan archives for Zip Slip indicators.
# GitHub Action for API key archive scanning
name: Scan API Key Archives
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Scan for Zip Slip
run: |
npm install -g middlebrick
middlebrick scan ./deploy/api-keys.zip --output json
- name: Fail on Zip Slip detection
if: contains(steps.scan.outputs.issues, 'Zip Slip')
run: exit 1