Skip to content

CWE-538: File and Directory Information Exposure

Overview

File and directory information exposure occurs when applications reveal sensitive file system metadata such as absolute paths, directory structures, file permissions, timestamps, or internal naming conventions. This information leakage typically manifests through error messages showing full file paths, directory listing pages, file metadata in HTTP headers, backup file discovery, or predictable file naming patterns. While not directly exploitable, this information aids attackers in reconnaissance, path traversal attacks, and understanding application architecture.

OWASP Classification

A01:2025 - Broken Access Control

Risk

Low to Medium: Exposed file paths reveal server configuration and application structure, enable more targeted path traversal attacks, disclose internal naming conventions allowing file enumeration, and expose backup or temporary files containing sensitive data. Combined with other vulnerabilities, this information significantly increases attack success rates.

Remediation Steps

Core principle: Never reveal internal file system paths, directory structures, or file metadata to untrusted users; use relative references and generic error messages.

Disable Directory Listings

Apache:

Options -Indexes

Nginx:

autoindex off;

Express.js:

// VULNERABLE - enables directory browsing
app.use(express.static('public', { index: false, dotfiles: 'allow' }));

// SECURE - disable directory listing
app.use(express.static('public'));  // Only serves files, not directories

Remove Path Information from Errors

# VULNERABLE - exposes full paths
try:
    with open(f'/var/www/app/data/{file_id}.json') as f:
        data = json.load(f)
except FileNotFoundError as e:
    return str(e), 404  # Shows: "/var/www/app/data/12345.json not found"

# SECURE - generic error message
try:
    with open(safe_file_path(file_id)) as f:
        data = json.load(f)
except FileNotFoundError:
    logger.error(f"File not found: {file_id}")
    return {"error": "Resource not found"}, 404

Use Opaque File References

# VULNERABLE - predictable file naming
file_path = f'/uploads/{user_id}/document_{doc_id}.pdf'

# SECURE - random identifiers
import uuid
file_id = str(uuid.uuid4())
# Store mapping in database
db.save_file_mapping(doc_id=doc_id, storage_path=file_id)

# Later retrieval uses opaque ID
stored_path = db.get_file_path(doc_id)

Strip File Metadata

Remove or sanitize metadata from HTTP responses:

from flask import send_file
import os

@app.route('/download/<file_id>')
def download(file_id):
    filepath = get_secure_path(file_id)

    # Don't reveal internal file structure
    return send_file(
        filepath,
        as_attachment=True,
        download_name='document.pdf',  # Generic name, not internal path
        mimetype='application/pdf'
    )

Protect Backup and Temporary Files

# Nginx - deny access to backup files
location ~* \.(bak|old|orig|save|swo|swp|tmp|temp)$ {
    deny all;
}

# Deny common editor backup patterns  
location ~ ~$ {
    deny all;
}

Remove Server Version Headers

# Nginx
server_tokens off;

# Apache
ServerTokens Prod
ServerSignature Off
// Express.js
app.disable('x-powered-by');

Implement Consistent File Access

# VULNERABLE - different error messages reveal file existence
if not os.path.exists(filepath):
    return "File not found", 404
if not user.can_access(filepath):
    return "Access denied", 403

# SECURE - same message for not-found and unauthorized
filepath = get_file_path(file_id)
if not filepath or not user.can_access(file_id):
    return "Resource not found", 404  # Same message for both cases

Dynamic Scan Guidance

For guidance on remediating this CWE when detected by dynamic (DAST) scanners:

Additional Resources