Description
Directory listing (CWE-548 — Exposure of Information Through Directory Listing) occurs when a web server is configured to display the contents of a directory as an HTML page when no index file (e.g., index.html, index.php) is present. Rather than returning a 403 Forbidden or 404 Not Found, the server presents a browsable file listing, similar to a file manager. This exposes the server's directory structure and any files within those directories to unauthenticated visitors.
Classified under A05:2021 — Security Misconfiguration, directory listing is generally low-severity in isolation but frequently acts as a discovery mechanism for higher-severity findings. The file listing itself may reveal backup archives, database dump files, configuration files, log files, source code, old deployment packages, or sensitive documents that were inadvertently left in web-accessible directories.
Directory listing is commonly enabled by default in older web server configurations (Apache's Options Indexes directive is historically default in some distributions). In modern cloud deployments, S3 bucket public listing presents a cloud-native equivalent. The finding is straightforward to remediate but is often overlooked because it does not produce errors and requires deliberate configuration.
How It Works
When a user or scanner requests a directory without an index file:
GET /uploads/ HTTP/1.1
Host: app.example.com
A misconfigured Apache server responds with an HTML directory listing:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head><title>Index of /uploads</title></head>
<body>
<h1>Index of /uploads</h1>
<pre>
Name Last Modified Size
backup_2025-08.zip 2025-08-01 14:22 48M
database_export.sql 2025-07-15 09:11 12M
.env.bak 2025-06-30 16:44 2.1K
config_old.php 2025-05-20 11:33 8.4K
</pre>
</body>
</html>
The attacker sees a backup archive, a database export, a .env backup file, and an old configuration file — all directly downloadable. Each of these files may contain credentials, schema information, and application secrets.
Recursive discovery extends the impact. Directory listings at the root level reveal subdirectories, each of which may also have listing enabled:
GET /admin/ → lists admin tools
GET /admin/scripts/ → lists automation scripts with hardcoded passwords
GET /logs/ → lists application log files containing user activity
Scanners automate this discovery. Tools like nikto, dirb, gobuster, and feroxbuster detect directory listing automatically and recursively enumerate the exposed file tree.
Even without backup files, directory listings assist attackers by revealing the server's technology stack, deployment patterns, file naming conventions, and development artifacts — information that informs more targeted attacks.
Impact
- Sensitive file discovery — backup archives, database exports,
.envfiles, and configuration files containing credentials are directly downloadable. - Source code exposure — PHP source files, Python scripts, and configuration files reveal implementation details enabling further attacks.
- Reconnaissance enablement — file names, modification dates, and directory structure reveal deployment patterns, technology choices, and naming conventions.
- Log file access — application and web server logs may contain session tokens, user activity, IP addresses, and debug information.
- Legacy file exposure — old configuration files, deprecated scripts, and abandoned code paths often have weaker security than current code.
Detection
- Request common directories directly — test
/uploads/,/backup/,/admin/,/logs/,/tmp/,/files/,/assets/,/static/,/scripts/, and/api/. A file listing response confirms directory listing is enabled. - Run nikto —
nikto -h https://app.example.comdetects directory listing automatically as part of its standard checks. - Check the web server configuration — in Apache: search for
Options Indexesinhttpd.confor.htaccess. In nginx: check forautoindex onin server or location blocks. - Test subdirectories of discovered paths — once a listing is found, recursively enumerate subdirectories. Tools like feroxbuster with the
-Dflag enumerate directories recursively. - Check for S3 bucket listing — if cloud storage is in use, test whether buckets allow public listing via
aws s3 ls s3://<bucket-name> --no-sign-request.
Remediation
Disable directory listing in the web server configuration.
For Apache, add to httpd.conf or .htaccess:
Options -Indexes
For nginx, ensure autoindex is not set to on (it defaults to off):
location / {
autoindex off;
}
For IIS, disable directory browsing in the IIS Manager or via web.config:
<directoryBrowse enabled="false" />
Place an empty index.html in every directory that must be served. This is a secondary defense — if listing is accidentally re-enabled, visitors see a blank page rather than a listing.
Move sensitive files outside the web root. Backup archives, database exports, configuration files, and log files must never reside in a directory served by the web server. Store them in non-web-accessible locations with appropriate access controls.
Enforce a deployment checklist. Verify that no listing-enabled directories and no sensitive files are present in the web root before and after each deployment.
