Disable Directory Listing in Apache & Nginx: Fix Options +Indexes Exposure

Directory listing (Options +Indexes) lets anyone browse your file structure. Here is how to disable it in Apache .htaccess and Nginx, and verify the fix.

Medium severity Infrastructure Security Updated 2026-03-01 Markdown

Web servers have served static files since the earliest days of the World Wide Web, and directory listing — showing a browsable index of files when no index.html exists in a directory — was a standard administrative convenience in 1990s server configurations. Apache's Options +Indexes and Nginx's autoindex on were designed for intentionally shared file servers, not for serving web applications. As web applications became the norm, these settings became a liability rather than a feature, and both Apache and Nginx now disable directory listing by default in modern configurations.

The vulnerability is primarily a reconnaissance enabler. When directory listing is active on any directory within a Laravel application's web root — public/css/, public/js/, public/uploads/, public/assets/ — an attacker can enumerate every file in that directory. This reveals old versions of JavaScript files with embedded API endpoints, backup files with .bak or .old extensions, uploaded files with sensitive names, and configuration files accidentally placed in the web root. Each discovered file is a potential attack vector.

The broader impact is that directory listing transforms a targeted attack into an open discovery exercise. An attacker doesn't need to guess filenames; they can browse your file structure like a file manager. Combined with tools like gobuster and dirsearch that test thousands of common filenames, even a partially visible directory structure significantly accelerates any attack. Modern web frameworks like Laravel route all requests through a front controller (public/index.php), making directory listing completely unnecessary for application functionality and actively harmful from a security perspective.

The Problem

Directory listing allows anyone to browse the file structure of your web server by visiting a directory URL that has no index file. This reveals file names, directory structures, backup files, configuration files, and other sensitive content that attackers use for reconnaissance. Even if individual files are not sensitive, the directory structure reveals your application architecture and potential attack targets.

How to Fix

  1. 1

    Disable directory listing in Nginx

    In your Nginx server block, ensure autoindex is off (this is the default, but it may have been enabled):
    server {
        # ...
        autoindex off;
    location / {
            try_files $uri $uri/ /index.php?$query_string;
        }
    }
    If autoindex on; appears anywhere in your configuration, remove it or change it to off:
    sudo grep -r 'autoindex on' /etc/nginx/
    sudo nginx -t && sudo systemctl reload nginx
  2. 2

    Disable directory listing in Apache

    Remove the Indexes option from your Apache configuration. In .htaccess:
    Options -Indexes

    Or in your Apache virtual host configuration:

    <Directory /var/www/yourapp/public>
        Options -Indexes +FollowSymLinks
        AllowOverride All
    </Directory>

    Restart Apache:

    sudo apachectl configtest && sudo systemctl restart apache2
  3. 3

    Add index files to directories that need them

    For any directory that should be web-accessible but does not have an index file, add an empty index.html:

    touch public/uploads/index.html
    touch public/assets/index.html
    Or use a PHP redirect:
    <?php
    // public/uploads/index.php
    header('Location: /');
    exit;

    This prevents directory listing even if the server configuration is accidentally changed.

How to Verify

Test directory listing by visiting directories without index files:

curl https://yourdomain.com/css/
curl https://yourdomain.com/js/
curl https://yourdomain.com/storage/

You should NOT see an HTML page listing files and directories. You should get either your application page (Laravel catches it), a 403 Forbidden, or a 404 Not Found response.

Prevention

Ensure directory listing is disabled in your server configuration templates. Include Options -Indexes in your .htaccess by default. Test for directory listing as part of your deployment checklist. Use StackShield to monitor for directory listing being enabled after server configuration changes.

Frequently Asked Questions

Is directory listing dangerous even if there are no sensitive files?

Yes. Directory listing reveals your file structure, which helps attackers understand your technology stack, find backup files (*.bak, *.old), discover hidden endpoints, and identify files to target. This reconnaissance information significantly speeds up an attack. Always disable it.

How does Laravel handle directory listing?

Laravel routes all requests through public/index.php, so directory listing is only a concern for directories within the public folder that contain static files (css, js, images, uploads). If a request hits a directory that Nginx/Apache serves directly (not through PHP), directory listing settings apply.

Does having an index.php in a directory prevent directory listing?

Yes, for that specific directory. If a directory contains an index.php or index.html, the web server serves that file instead of showing a directory listing. However, this only protects the directory that has the index file, not subdirectories. The correct fix is to disable directory listing at the server configuration level rather than adding index files to every directory.

How do I check if directory listing is enabled on my server?

Visit a directory URL that contains files but no index file — for example, https://yourdomain.com/css/ or https://yourdomain.com/js/. If you see an HTML page listing filenames with links, directory listing is on. You can also test with curl: curl https://yourdomain.com/css/ | grep -i "index of" — a match confirms directory listing is enabled.

What is the most secure Nginx configuration for a Laravel application?

Point the root at /public, use try_files $uri $uri/ /index.php?$query_string, ensure autoindex is off (the default), block dotfiles with location ~ /\. { deny all; }, and disable PHP execution outside index.php with a location that only allows .php files at the root level. Laravel Forge generates a well-hardened Nginx configuration that serves as a good reference.

Free security check

Is your Laravel app exposed right now?

34% of Laravel apps we scan have at least one critical issue. Most teams don't find out until something breaks. Our free scan checks your live application in under 60 seconds.

18% have debug mode on
72% missing security headers
12% have exposed .env
Scan My App Free No signup required. Results in 60 seconds.