Rate this page

Allow CGI scripts within the document root of an Apache webserver

Tested on

Debian (Etch, Lenny, Squeeze)
Ubuntu (Lucid, Maverick, Natty)


To allow CGI scripts to execute from within the document root of an Apache webserver


By default Apache requires that all CGI scripts be placed in the directory /usr/lib/cgi-bin/, away from the static content of the website. This can be inconvenient if it prevents closely related files from being located near to each other:

These instructions describe an alternative method whereby CGI scripts are identified by means of a particular file extension. Scripts can then be placed alongside related static content.


Suppose that you are developing a gaming website for the domain wopr.norad.mil. The document root is /var/www/. Each game has a subdirectory beneath the root, for example /var/www/chess/ or /var/www/tic-tac-toe.

You wish to locate all of the files for each game (including any CGI scripts) alongside each other in the relevant subdirectory. The CGI scripts may be distinguished from files to be served statically by the fact that they end with the extension .cgi.

The existing configuration for the document root is as follows:

DocumentRoot /var/www

<Directory /var/www>
 Options None
 AllowOverride None
 Order allow,deny
 Allow from all



Three steps are required:

The configuration will need to be reloaded afterwards. See Cause a system service to reload its configuration for instructions.

Associate the cgi-script content handler with the required file extension

Use the AddHandler directive to associate files that end with the extension .cgi with the cgi-script content handler:

AddHandler cgi-script .cgi

A suitable location for this directive would be within the <Directory> container corresponding to the document root (/var/www in this case), but it can be used in any configuration context if required.

Ensure that the +ExecCGI option is set

Apache will not execute a CGI script unless it is located in a directory for which the ExecCGI option is enabled. This can be done using an Options directive:

Options +ExecCGI

A suitable location would be alongside the AddHandler directive discussed above. The required form of the directive will depend on whether the directory in question had any pre-existing options specified:

Ensure that the CGI scripts are executable

Apache will not execute a CGI script unless its file mode indicates that it is executable. Depending on what the script does it may be acceptable for it to be executable by any user:

chmod +x *.cgi

or you may prefer to make it usable only by the owner of the web server process. On Debian-based systems this is typically www-data:

chown www-data:www-data *.cgi
chmod 700 *.cgi

whereas on Red Hat-based systems it would typically be the apache user:

chown apache:apache *.cgi
chmod 700 *.cgi

Resulting configuration

The resulting configuration for the document root would be as follows:

DocumentRoot /var/www

<Directory /var/www/>
 Options ExecCGI
 AllowOverride None
 Order allow,deny
 Allow from all
 AddHandler cgi-script .cgi


Excluding a directory

Execution of CGI scripts can be disabled within a directory by turning off the ExecCGI option. For example, to do this within the directory /var/www/upload:

<Directory /var/www/upload>
 Options -ExecCGI

Security Considerations

It can be argued that allowing CGI scripts to execute from within the document root is more risky than requiring them to be placed in a separate location such as /usr/lib/cgi-bin. The main points of concern are that:

None of these prevent the web server from being run securely, however they could make the task more difficult or prone to error. The advice given in the Apache documentation is that:

CGI programs are often restricted to ScriptAlias'ed directories for security reasons. In this way, administrators can tightly control who is allowed to use CGI programs. However, if the proper security precautions are taken, there is no reason why CGI programs cannot be run from arbitrary directories.

Further Reading

Tags: apache