# Fix Apache Directory Listing Exposing Sensitive Files

A security scan reveals that your Apache server exposes directory listings, allowing anyone to browse your file structure. When visiting https://example.com/uploads/, instead of a 403 Forbidden or a custom index page, visitors see a complete listing of all files in the directory.

The Problem: Options Indexes Enabled

The default Apache configuration on many distributions includes Options Indexes, which enables automatic directory listing when no index file (index.html, index.php) exists in a directory:

apache
<Directory /var/www/html>
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all granted
</Directory>

The Indexes keyword is the culprit. When Apache receives a request for a directory and no DirectoryIndex file exists, it generates an HTML page listing all files and subdirectories.

Disabling Directory Listing Globally

Remove Indexes from the Options directive:

apache
<Directory /var/www/html>
    Options FollowSymLinks
    AllowOverride None
    Require all granted
</Directory>

Without Indexes, Apache returns 403 Forbidden when a directory has no index file. This is the correct security posture for most web applications.

Disabling for Specific Directories Only

If you need directory listings for a specific directory (e.g., a public downloads section) but want to disable them everywhere else:

```apache # Global: disable <Directory /var/www/html> Options FollowSymLinks Require all granted </Directory>

# Exception: enable for downloads only <Directory /var/www/html/downloads> Options Indexes FollowSymLinks Require all granted

# Customize the listing appearance IndexOptions FancyIndexing HTMLTable VersionSort NameWidth=* IndexIgnore .??* *.php *.sql *.bak *.conf *.env HeaderName /downloads/HEADER.html ReadmeName /downloads/README.html </Directory> ```

The IndexIgnore directive hides sensitive file patterns from the listing. IndexOptions controls the appearance.

What Attackers Look For in Directory Listings

An exposed directory listing reveals:

  • Database backup files (backup.sql, dump-2026.sql)
  • Configuration files (.env, config.php.bak)
  • Version control directories (.git/, .svn/)
  • Temporary files (upload_tmp_abc123)
  • Log files (access.log, error.log)
  • Old versions of files (index.php.old, site.bak)

Test your own server:

bash
curl -s https://example.com/uploads/ | grep -c "<a href="
curl -s https://example.com/.git/ | head -5
curl -s https://example.com/config/ | head -10

If any of these return file listings or sensitive content, directory listing is enabled where it should not be.

Additional Hardening

Beyond disabling Indexes, add these protections:

```apache # Block access to hidden files and directories <DirectoryMatch "/\."> Require all denied </DirectoryMatch>

# Block specific file types globally <FilesMatch "\.(env|sql|bak|conf|config|ini|log|sh)$"> Require all denied </FilesMatch>

# Block .git, .svn, .hg directories RedirectMatch 404 /\.(git|svn|hg) ```

Finding All Directories with Indexes Enabled

Search your entire Apache configuration:

bash
grep -rn "Options.*Indexes" /etc/apache2/
# or
grep -rn "Options.*Indexes" /etc/httpd/

Check each result. If Indexes appears in a <Directory> block that should not have public listings, remove it. After making changes:

bash
sudo apachectl configtest
sudo systemctl reload apache2

Verify the fix by visiting known directory URLs in a browser and confirming you get 403 Forbidden instead of a file listing.