How to Prevent Directory Listing in Apache

How to prevent directory listing in Apache

One of the first things I check during any security audit is whether directory listing is enabled somewhere it shouldn’t be. It’s a small, easy-to-overlook setting, but I’ve personally found exposed backup folders, config files, and even database dumps sitting in plain sight simply because directory listing was left on. Here’s how I lock it down properly.

What Is Directory Listing and Why It’s a Problem

When a visitor requests a directory URL (like example.com/uploads/) and there’s no index file (index.html, index.php, etc.) present, Apache’s default behavior — if directory listing is enabled — is to generate and display a full list of every file in that folder. That means anyone can browse your file structure, potentially discovering:

  • Backup files (.sql, .zip, .bak)
  • Configuration files that shouldn’t be public
  • Uploaded files never meant to be linked publicly
  • Source code or log files

Prerequisites

  • Root or sudo access to the server, or .htaccess access on shared hosting
  • Apache 2.4+
  • Access to edit virtual host configuration files or .htaccess

Step 1: Check If Directory Listing Is Currently Enabled

The fastest way I check is simply visiting a directory URL without an index file in the browser, or using curl:

curl -I https://example.com/uploads/

If you see a directory listing page (usually titled “Index of /uploads”) when visiting that URL directly, it’s enabled and needs to be fixed.

Step 2: Disable Directory Listing Globally

The core fix is removing the Indexes option from your Options directive. I set this at the root level so it applies everywhere unless explicitly overridden:

<Directory /var/www/>
    Options -Indexes +FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

The minus sign before Indexes explicitly disables it. Note I keep +FollowSymLinks since that’s usually needed for normal site functionality and isn’t a security risk on its own.

Step 3: Disable It for a Specific Directory

If you only need to lock down one particular folder (say, an uploads directory) rather than the whole site:

<Directory /var/www/example.com/uploads>
    Options -Indexes
</Directory>

Step 4: Using .htaccess (Shared Hosting)

On shared hosting where you don’t have access to the main config, I place this in a .htaccess file in the target directory:

Options -Indexes

This requires AllowOverride Options (or AllowOverride All) to be set in the main server configuration for that directory.

Step 5: Restart Apache and Verify

If you edited the main configuration (not .htaccess, which applies immediately), restart Apache:

sudo apachectl configtest
sudo systemctl restart apache2

Then verify the fix:

curl -I https://example.com/uploads/

You should now see a 403 Forbidden response instead of a directory listing.

Step 6: Add a Custom Error Page (Optional but Recommended)

Rather than showing Apache’s default 403 error page, which reveals it’s an Apache server, I usually configure a custom error page for a more polished, less information-revealing experience:

ErrorDocument 403 /error-pages/403.html

Step 7: Add Index Files as an Extra Layer

Even with Options -Indexes set, I often add a blank index.html or index.php file to sensitive directories as a belt-and-suspenders approach — some misconfigurations or module interactions can behave unexpectedly, and an index file guarantees nothing gets listed regardless:

echo "" > /var/www/example.com/uploads/index.html

Step 8: Audit Your Entire Site for Exposed Directories

I don’t stop at the obvious folders. I do a full audit of the site structure and check every directory that doesn’t need to be publicly browsable — this often includes /backups, /logs, /tmp, /includes, and similar folders that developers create during the build process and forget to lock down.

find /var/www/example.com -type d

I go through this list methodically and confirm Options -Indexes applies globally so nothing is missed.

Real-World Use Case

During an audit for a client running an older custom CMS, I found a /backups folder with directory listing enabled, containing three months of unencrypted full-site backup ZIP files — including the database dump with hashed passwords and API keys. Disabling directory listing site-wide and moving that backup folder outside the web root entirely closed the exposure immediately.

Common Mistakes to Avoid

  • Only disabling it for one folder while forgetting others — I always set Options -Indexes at the root level so it applies everywhere by default.
  • Storing sensitive files inside the web root at all — even with directory listing disabled, files can still be directly accessed if someone guesses or finds the exact filename. Sensitive files like backups should live outside the publicly served directory entirely.
  • Assuming a CMS handles this automatically — many do by default, but custom-built sites and older CMS installs often don’t.
  • Forgetting to check subdirectories created by plugins or third-party tools, which sometimes set their own permissive Options directive.

Troubleshooting Tips

If Options -Indexes doesn’t seem to take effect, check for a more specific <Directory> block further down in the configuration (or a .htaccess file within that specific folder) that might be re-enabling Indexes and overriding your global setting — Apache directives cascade, and more specific rules win. Also confirm AllowOverride is actually permitting .htaccess changes if you’re relying on that method rather than the main config.

Security and Performance Best Practices

  • Store backups, logs, and sensitive files outside the web root entirely rather than relying solely on directory listing being disabled.
  • Combine this fix with restricting access to sensitive file extensions (.sql, .bak, .env) as covered in my Apache vulnerabilities post.
  • Regularly audit your directory structure, especially after installing new plugins or third-party tools that create their own folders.
  • Use a security scanner (like Nikto) periodically to catch exposed directories you might have missed manually.

Frequently Asked Questions

Does disabling directory listing hurt SEO? No. Search engines don’t need directory listings to index your site properly — they follow your actual linked pages and sitemap.

Is an empty index.html file enough on its own, without Options -Indexes? It prevents listing for that specific folder as long as the index file remains present, but I still recommend setting Options -Indexes globally as the more robust, intentional fix.

Will this break any legitimate functionality on my site? No, disabling directory listing has no effect on normal site operation — visitors only ever notice a difference if they were directly browsing a directory URL without an index file, which isn’t standard navigation.

How do I know if directory listing was already exploited? Check your access logs for repeated requests to directory paths ending in / from unfamiliar IPs, which can indicate someone was browsing your file structure.

Summary and Key Takeaways

Disabling directory listing is a five-minute fix with a real security payoff — it’s one of those settings that costs nothing to implement but has caused real damage in the audits I’ve done when left on by default. Set Options -Indexes globally, verify it with a quick curl test, and go a step further by moving genuinely sensitive files outside the web root entirely.

References

Total
1
Shares

Leave a Reply

Previous Post
How to configure a firewall for Apache

How to Configure a Firewall for Apache

Next Post
How to restrict access to a specific IP address or range

How to Restrict Access to a Specific IP Address or Range in Apache

Related Posts