Directory listing: why it exposes your files and how to turn it off
Auto-generated folder listings reveal backups, logs and uploads. How to find them on your site and switch them off.
Typical severity: High · Checked by NovaPentest module: Directory Listing
What it is
Directory listing, also called auto-indexing, is a web server feature that generates an HTML page listing the contents of a folder when a request points to a directory and no index file such as index.html is present. Apache calls it Options Indexes, nginx calls it autoindex, IIS calls it Directory Browsing, and Python's built-in http.server does it by default.
The feature is useful on an internal file server and almost never wanted on a public website. On a production site, the files in a directory are meant to be reached through links your application publishes, not browsed as a catalogue.
The control is simply that the server refuses to list directories. A request for /uploads/ should return 403 or 404, or an index page you wrote, never an automatically generated list of file names, sizes and modification dates.
Listing is usually enabled by accident: a default configuration nobody reviewed, a new static folder added under an old virtual host, a container image built from a base that turns it on, or a storage bucket exposed through a proxy. It is also often inherited: enabling it for one path in Apache applies it to every subdirectory below.
Turning listing off does not protect a file whose URL is already known. It removes the easy way to discover which files exist, which is why it matters most in folders that accumulate content over time, such as uploads, exports, backups and logs.
How it is exploited
A directory listing turns guesswork into reading. Anyone who opens the folder sees every file in it, including files that were never linked from the site and that the owner may have forgotten exist.
The files that surface this way are rarely the ones meant to be public. Common examples are database dumps or site archives left in a backup folder, copies of configuration files saved with a .bak or .old extension that the server now returns as plain text, log files containing user email addresses, IP addresses or internal errors, exported spreadsheets and invoices in an uploads folder, and user-uploaded documents whose privacy depended on nobody knowing the file name.
For users, the consequence is direct exposure of their personal data without any breach of the application itself. For the site, a leaked configuration or backup can contain database credentials or API keys, turning an information leak into a full compromise.
The listing also reveals structure: framework names, version numbers in file names and the layout of the application, which makes any other weakness easier to find.
Search engines and archive services sometimes index these pages, so a listing can remain discoverable for a while after it is fixed. Removing the listing is not enough if sensitive files were exposed; they should be deleted from the web root and any credentials in them rotated.
How to detect it
NovaPentest's Directory Listing module requests ten common paths under the target: /, /images/, /uploads/, /static/, /assets/, /backup/, /files/, /logs/, /data/ and /tmp/. For every path that returns a success status, it searches the response body for typical listing signatures such as Index of /, Parent Directory or Directory listing for, and reports each match as a separate High finding naming the path. Because it actively probes paths, this module runs in authenticated full scans and is not part of the free passive scanner at novapentest.com/scan.
The approach has limits. Only those ten paths are tested, so a listing on /media/, /wp-content/uploads/ or any application-specific folder will not be found. Detection is by text match, so a server with a custom or translated listing template may be missed, and an ordinary page that happens to contain the phrase Parent Directory or Index of / will be reported as a listing. Redirects are followed, so the finding reflects wherever the path ended up.
To verify by hand, request each folder your site serves static files from and look at the response: curl -s https://example.com/uploads/ | head -n 20. A listing is obvious, typically an Index of heading and a table of file names. Check the status line with curl -sI https://example.com/uploads/; 403 or 404 is what you want. Test with and without the trailing slash, and include folders created by plugins, build tools and upload features. Searching a search engine for site:example.com intitle:"index of" can show listings that were already indexed.
How to fix it
1. Turn listing off globally, then re-enable it only where you truly need it, which on a public site is almost never.
2. nginx: autoindex is off by default, so search the configuration for autoindex on; and remove it, or set autoindex off; in the http or server block.
3. Apache: remove Indexes from the Options directive, for example with Options -Indexes in the main configuration, the relevant Directory block or an .htaccess file. Because Options are inherited, check parent directories too.
4. IIS: in IIS Manager open Directory Browsing and choose Disable, or set the enabled attribute of the directoryBrowse element to false under system.webServer in web.config.
5. ASP.NET Core: do not call app.UseDirectoryBrowser() or services.AddDirectoryBrowser() in production; UseStaticFiles on its own does not list directories.
6. Express: serve static files with express.static, which does not list directories, and remove serve-index if it is installed.
7. Clear the web root of anything that is not meant to be served. Backups, dumps, logs and exports belong outside the document root or in private storage with access control. A server that refuses to list a folder will still hand over a file whose name someone guesses.
8. Protect upload folders by serving user files through application code that checks permissions, or with random, unguessable names on storage that does not allow listing. For S3 or similar services, keep the bucket private and use signed URLs.
9. If sensitive files were exposed, delete them, rotate any credentials they contained, and request removal of the URLs from search engines.
10. Re-test each folder with curl and add the check to your deployment verification.
Check your own site
Start with the free passive scan: no account needed, and you get an A to F grade covering headers, TLS, cookies, DNS and other configuration a visitor can observe. It does not send attack payloads, so it will not confirm every class of flaw. The full scan, available with a free account, runs the active checks, including the one described on this page.