Weakness reference
CWE-641

Improper Restriction of Names for Files and Other Resources

This weakness occurs when an application allows users to specify or influence the names of files, directories, or other resources without proper validation or…

01Summary

This weakness occurs when an application allows users to specify or influence the names of files, directories, or other resources without proper validation or restriction. An attacker can exploit this to access files or resources they shouldn't be able to reach — such as configuration files, private data, or system files — by crafting requests with unexpected names or paths.

02How It Happens

Applications often accept user input to determine which file or resource to load, display, or process. If the application doesn't validate or restrict what names are allowed, an attacker can supply names that point to unintended locations. This commonly happens when:

- A file name or path is taken directly from user input without checking against an allowlist of permitted names. - Path traversal sequences (like ../) are not filtered or blocked. - The application assumes user input will only reference files in a specific directory, but doesn't enforce that assumption. - Resource identifiers (database table names, API endpoints, configuration keys) are constructed from untrusted input without validation.

The core issue is trusting the user to request only legitimate resources, rather than explicitly controlling which resources are accessible.

03Real-World Impact

Unrestricted resource names can lead to unauthorized file access, exposure of sensitive configuration files (containing database credentials or API keys), reading private user data, or accessing system files. In some cases, if the application also allows writing to resources, an attacker could overwrite critical files or inject malicious content. The severity depends on what resources are accessible and what the application does with them.

04Vulnerable & Fixed Patterns

Vulnerable pattern
import os

def serve_document(filename):
    # User supplies filename directly; no validation
    filepath = os.path.join('/var/documents', filename)
    with open(filepath, 'r') as f:
        return f.read()

# Attacker requests: serve_document('../../../etc/passwd')
# Result: reads /etc/passwd instead of a document

Why it's vulnerable:
The filename is used directly to construct a file path without checking whether it contains path traversal sequences or references files outside the intended directory.

Fixed pattern
import os

ALLOWED_DOCUMENTS = {'report.pdf', 'summary.txt', 'data.csv'}

def serve_document(filename):
    # Validate against an allowlist of permitted names
    if filename not in ALLOWED_DOCUMENTS:
        raise ValueError(f"Document '{filename}' not found")
    
    filepath = os.path.join('/var/documents', filename)
    with open(filepath, 'r') as f:
        return f.read()
Vulnerable pattern
<?php
// User supplies filename via GET parameter
$filename = $_GET['file'];
$filepath = '/var/documents/' . $filename;

// Attacker requests: ?file=../../../etc/passwd
// Result: reads /etc/passwd
if (file_exists($filepath)) {
    echo file_get_contents($filepath);
}
?>

Why it's vulnerable:
The filename from user input is concatenated directly into the file path without validation, allowing path traversal attacks.

Fixed pattern
<?php
$allowed_files = array('report.pdf', 'summary.txt', 'data.csv');
$filename = $_GET['file'] ?? '';

// Validate against an allowlist
if (!in_array($filename, $allowed_files, true)) {
    die('File not found');
}

$filepath = '/var/documents/' . $filename;
if (file_exists($filepath)) {
    echo file_get_contents($filepath);
}
?>

05Prevention Checklist

Use an allowlist:
Define exactly which file or resource names are permitted, and reject anything else. This is the most effective defense.
Avoid path traversal:
Never allow user input to contain ../, ..\\, or other directory navigation sequences. If you must accept paths, use realpath() or equivalent to resolve them and verify the result is within the intended directory.
Separate user input from resource selection:
Use numeric IDs or tokens to reference resources, then map them server-side to actual names. For example, accept ?doc_id=5 and look up the filename in a database, rather than accepting the filename directly.
Use basename() or equivalent:
If you must extract a filename from a path, use language-native functions that strip directory components, then validate the result.
Restrict file permissions:
Ensure the application process runs with minimal file system permissions — it should only be able to read/write files it legitimately needs.
Log and monitor:
Track requests for unusual or suspicious file names, and alert on repeated access attempts to restricted resources.

06Signs You May Already Be Affected

Check your application logs for requests containing path traversal sequences (../, ..\\) or attempts to access files outside your intended directory (e.g., requests for /etc/passwd, .env, web.config, or wp-config.php). Unexpected or unauthorized files appearing in your document directories, or reports of users accessing data they shouldn't have, may also indicate exploitation. Review file access logs to see if sensitive configuration files have been read recently.

07Related Recent Vulnerabilities