Using environment variables
This script demonstrates the usage of CGI environment variables.
Programming Issues
This script uses a template HTML
file for its output. Rather than using print
to output the body of our document, we assign it to
the variable $mainmatter
and pass that to the printHTMLOutputFromTemplate
subroutine at
the end of the script.
Firstly, we loop through all the environment variables using Perl's foreach
operator to accomplish
two tasks:
- Assign the value
<NONE>
to any environment variables which are defined, but empty; and - Replace the HTML special characters
<
,>
,&
and"
with their corresponding character entity references. We do this for two reasons:- Some environment variables contain these characters. In particular,
QUERY_STRING
contains a list of key/value pairs separated by the&
character. If we do not replace these with their appropriate character entity references, the user agent may not display or interpret them properly; and - For security. Some environment variables, particularly
HTTP_USER_AGENT
andHTTP_REFERER
, are passed directly from the user agent. With a well-behaved user agent, the user has no control over the contents of these variables, but we cannot rely on this being the case. It would be a trivial exercise even for a beginning network programmer to "forge" HTTP headers (the echo client C programming example on this web site could be adapted to this purpose very easily indeed), and to insert, for instance, the following header:
to view the contents of your server machine's password file if your server is set up to parse the output from CGI scripts and does not have aUser-Agent: <--#include file="/etc/passwd" -->
DOCUMENT_ROOT
set properly. If we replace the<
character with the character entity reference<
then the output will not be interpreted as a SSI by the server and this attempted attack will be stopped in its tracks. This is a good example of where beginning CGI authors can be caught out by security issues. Most beginning CGI authors know not to trust user input, but may not consider the need to check input passed to the script by the server itself, in this case, in the environment variables. Again, when dealing with CGI security, the motto is "Trust nobody!"
- Some environment variables contain these characters. In particular,
Secondly, we present an HTML table showing some of the more commonly available environment variables. We also
give an example of explicitly determining the user's browser along with its major and minor version numbers, where
available, and the user's operating system from the HTTP_USER_AGENT
environmental variable. This is
a common technique for implementing conditional HTML, where different code is servers to different
user agents depending on their capabilities. The Browser
Capabilities Project maintains a list of known user agents and their identifiers along with a database of
their capabilities for this purpose, which is far more comprehensive than the current example which is merely
a demonstration.
Thirdly, we present a few paragraphs showing how some of the environment variables might be used to identify the user agent, the remote IP address, and so on.
Finally, we again use Perl's foreach
operator to output all the environment variables implemented
by the server and their contents. In the source code this section is commented out,
and it is not implemented on the CGI script used on this site, as it is generally considered to be a bad idea to
reveal the contents of all the server's environment variables to anybody who cares to look at them, since they
may reveal information (such as absolute paths and server software) that may be useful to an attacker. If you want
to view these results on your own web server, then simply uncomment that section, but do so at your own risk.
Note that all the environment variables is not quite correct. Many times some environment variables may
only be defined in certain circumstances. For instance, the CONTENT_LENGTH
environment variable
may only be defined when the REQUEST_METHOD
is POST
. Similarly, HTTP_REFERER
may not be defined if the script was called directly, rather than from a hyperlink on another page.
A list of standard CGI environmental variables is available.
Usage
Just run the CGI script by requesting it with the link: http://www.paulgriffiths.net/cgi-bin/envvars.pl.