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 DirectoryIndex directive

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

Indexes

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.

A screenshot that shows the contents of the uploads folder. It lists various music files. Users can download the files and navigate to other folders.
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.

Disabling directory indexes

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.

The Indexes page in cPanel. The page lists all folders and shows if indexes are currently allowed. Each folder has an Edit button that lets you change the setting for the folder.
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.

You have a few options when you edit the indexing setting for a folder in cPanel. You can use the default setting, disable indexes or define how you want directory listings to look.
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.

When directory listing are disables users see an error 403 (forbidden) when they try to access the directory. cPanel servers use a very pretty 403 page. It shows the number 403 in a huge font, and it explains that access to the resource is forbidden.
Image: viewing the contents of directories is no longer allowed.

Fancy options

The other two options define how directory listings are formatted:

  • The default option is Show Filename and Description. This shows the file name, last modified date, file size and an optional description. Users can download the files and the columns can be sorted. So, you can sort the files by name, date or size.
  • Show Filename Only produces just a list with file names. Users can again download the files.

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

Inheritance

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.