17 December 2021
Apache uses the DirectoryIndex directive to set a default index page for your website. Usually, valid index pages include index.html and index.php. Apache automatically serves an index file if it exists. That is handy, as it means you can view a website by typing the website name, such as example.com. You don’t need to specify that you want to view example.com/index.html or example.com/index.php.
In this article I briefly look at the DirectoryIndex directive. I then look at what happens if there is no index file in a directory.
The default index pages are stored in the main Apache configuration file. On cPanel servers this is a very long list with possible files:
# grep ^DirectoryIndex /etc/httpd/conf/httpd.conf DirectoryIndex index.html.var index.htm index.html index.shtml index.xhtml index.wml index.perl index.pl index.plx index.ppl index.cgi index.jsp index.js index.jp index.php4 index.php3 index.php index.phtml default.htm default.html home.htm index.php5 Default.html Default.htm home.html
The order of the files is important. When you visit example.com Apache first checks if there is a file named index.html.var, and if so it serves the file. Next, it looks for a file named index.htm, and so forth.
It is worth noting that index.html is listed before index.php. If you install WordPress in a directory that already contains an index.html file then you won’t see your WordPress website. Instead, you see the index.html file. You can fix that by changing the default index page in your .htaccess file. For instance, you can change it to this:
DirectoryIndex index.php index.html
If there is no index file in a directory then Apache either shows a “forbidden” error or lists the contents of the directory. By default, cPanel servers allow directory indexes. This is again defined in the main Apache config file:
# grep -E "Options ?Indexes" /etc/httpd/conf/httpd.conf Options Indexes FollowSymLinks
This is arguably a bad default setting. It means that anyone can view the contents of directories that don’t have an index file. For instance, anyone can lists the contents of folders in the wp-content/uploads directory.
Image: the contents of a WordPress uploads folder.
In general, it is a good idea to disable directory indexes. The feature is useful if you want people to view and download files. For instance, if you run a software repository then you can easily let users download files. Obviously, that is an edge-case. It does not apply to “normal” websites.
As an aside, the reason cPanel servers allow directory listings is that there is no index file on a newly created cPanel account. If you got a brand new domain and cPanel account you would get an error 403 when you visit your domain. That could be confusing, and you therefore instead see the contents of the public_html folder.
To disable directory indexing you can override the value in your .htaccess file. You can do that via the cPanel control panel. The Advanced » Indexes interface let’s you specify if indexes should be enabled or disabled for individual folders.
Image: the Indexes page lets override the default directory indexes setting.
By default, all directories inherit the global setting defined in the main httpd.conf file. You can change the default setting for individual folders. For instance, to disable directory indexes for your entire website you can edit the setting for the public_html folder.
Image: the indexes options for the public_html folder.
As the name suggests, No Indexing disables directory listings. People trying to view the contents of a WordPress uploads directory now get an error 403.
Image: viewing the contents of directories is no longer allowed.
The other two options define how directory listings are formatted:
cPanel’s Indexes option simply adds a rule to a .htaccess file. This rule disables indexes:
Options -Indexes
The Show Filename and Description rule looks as follows:
Options +Indexes IndexOptions +HTMLTable +FancyIndexing
The IndexOptions
line is redundant, as Apache uses the options by default. Still, it can’t hurt to define exactly how you want folder listings to work.
And as you might expect, the Show Filename Only option looks like so:
Options +Indexes IndexOptions -HTMLTable -FancyIndexing
It is worth noting that the Indexes rule is inherited. So, when you change the setting for the public_html directory your whole website is protected. If you want you can next override the setting in one or more subfolders. For instance, if you want you can add Options +Indexes
to a .htaccess file in a /public_html/wp-content/uploads folder. In that case the uploads directory, including all its subdirectories, can be viewed in web browsers.