Home Articles FAQs XREF Games Software Instant Books BBS About FOLDOC RFCs Feedback Sitemap

Related items

CGI Security : Better Safe than Sorry

Creating a Page Counter In Perl

Speed Thrills : CGI Please ... and Fast!

CGI Programming Made (Relatively) Easy Using Libraries

Random and Recursive Crypting using Salt on Unix and Win32

Timestamping an HTML Document

Deleting Files in Perl

Creating a mailing list using Perl

Reading and Writing to Files on the Server

Server Side Includes and CGI Security

Server-Side Includes and its Extensions

You are here: irt.org | Articles | CGI & Perl | Server-Side Includes and its Extensions [ previous next ]

Published on: Saturday 12th June 1999 By: Pankaj Kamthan


There are various instances when you want to output a document with only a minimum amount of dynamic information, for example, displaying the current date and time. There are various ways of doing that with server-side interaction. One option is writing a CGI script. However, that is not necessary. You can use a powerful feature called SSI's, or its extension XSSI's, to do that, and this is the basis of this article.

We assume that the reader has some background on HTML, CGI and Perl. Although not necessary, it will be useful to have some familiarity with server configuration files, like that of Apache.

For concepts that apply both to SSI's as well as XSSI's, we shall use the symbol (X)SSI.

Part I. Server-Side Includes

SSI's were first introduced in the NCSA WWW server, the predecessor of Apache. They are directives which you can place into your HTML documents to execute other programs or output such data as environment variables and file statistics. Unfortunately, not all servers support these directives. For example, the CERN server does not support SSI's, but (as we shall see later) many other servers can. (In such a case, there is a Perl program fakessi.pl that you can use as a CGI to emulate SSI's.)

Advantages of SSI's

SSI Editing

Emacs with html-helper-mode can be used to edit HTML, and hence files with SSI directives. However, it lacks explicit SSI support. (See also the section on XSSI Editing.)

SSI Environment Variables

All environment variables that are available to CGI programs are also available to SSI directives. There are also six environment variables that are exclusively available to SSI directives:

Environment Variable

DATE_GMT Current date and time in GMT (Greenwich Mean Time).
DATE_LOCAL Current date and time in the local time zone.
DOCUMENT_NAME The current filename.
DOCUMENT_URI Virtual path (relative to the document root) to the file.
LAST_MODIFIED Last modification date and time for current file.
QUERY_STRING_UNESCAPED Undecoded query string with all shell metacharacters escaped with a "\".

Table. 1

SSI Directives

The document is parsed as an HTML document, with all include directives embedded as SGML comments within the document. )This is in case the document should ever be transferred without being parsed.) Each directive has the following format:

<!--#command parameter="argument"-->

Each command takes different parameters, and most only accept one parameter at a time. Each SSI command begins with a pound sign (#). Each parameter to the command, called a tag or argument, ends with an equal sign (=), and then takes a value. The following sections discuss the syntax and meaning of each of the SSI commands in detail. Appendix I provides a summary.


The config directive controls various aspects of file parsing, and allows you to select the way error messages, file size information, and date and time are displayed. It has three valid arguments:


If you use the include command to insert a file that doesn't exist, the server will output a default error message similar to the following:

[an error occurred while processing this directive]

By using the config command, you can modify this message. If you want to set the message to "Error. Please contact einstein@ias.edu" you can use the following:

<!--#config errmsg="Error. Please contact einstein@ias.edu."-->

You can also set the file size format that the server uses when displaying information with the fsize command. For example, this command:

<!--#config sizefmt="abbrev"-->

will force the server to display the file size rounded to the nearest kilobyte (K). You can use the argument "bytes" to set the display as a byte count:

<!--#config sizefmt="bytes"-->


The echo directive returns the value of special SSI variables as well as other environment variables. Any dates are printed subject to the currently configured timefmt.

The only parameter to this directive is var, whose value is the name of the variable you wish to echo.


If somewhere in your document you have the following:

<!--#echo var="DOCUMENT_NAME"-->
<!--#echo var="DOCUMENT_URI"-->
<!--#echo var="LAST_MODIFIED"-->

In that part of the document, you will see the display of name, URL (although the variable is titled DOCUMENT_URI), and modification time of the document.

The next example, displays the IP name or address of the serving machine, the remote host name, and the local time.

<!--#echo var="SERVER_NAME"-->
<!--#echo var="REMOTE_HOST"-->
<!--#echo var="DATE_LOCAL"-->


The include directive embeds the text of a document into the parsed document. Any included file is subject to the usual access control. include serves the same function in HTML as include does in languages like C or C++: it helps to make code more modular and maintainable by setting all the items that need to appear on nearly every page into a small set of files, and then including a reference to the appropriate file instead of repeating that file's contents in a given location.

It has two valid arguments:


Examples of use are:

<!--#include file="foo.txt"-->
<!--#include virtual="/path_to/foo.txt"-->


The exec directive executes external programs and inserts output in current document. It must be activated to be used. It has two valid arguments:


In this example, we use the UNIX finger command to retrieve some information about the user:

<!--#exec cmd="/path_to/finger $REMOTE_USER@$REMOTE_HOST"-->

You should enclose the output from an external command in a <PRE>...</PRE> block, so that whitespace is preserved, and if there is any HTML code within the data output by the external program, the browser will interpret it.

This next example is a simple user access counter using exec cmd. Create a file counter.txt and do the following (on, say, UNIX command prompt):

$echo "0" > path_to/counter.txt
$chmod 777 path_to/counter.txt

And then in your HTML:

<!--#exec cmd="path_to/perl -pi -e '$_++' path_to/counter.txt;cat path_to/counter.txt"-->

The path_to Perl and the counter file in the above script should be configured for your system. There are two obvious limitations of this: (1) it requires the counter data file (counter.txt) to exist with appropriate read/write permissions, and (2) it does not lock counter.txt file, which is essential for handling concurrent accesses to the page.

An example that circumvents these problems to some extent and uses exec cgi will be shown later.


The fsize directive inserts the size of a specified file (relative to the server document root) in bytes. Valid arguments are the same as with the include command. The size of the file can be formatted using the sizefmt parameter of the config command.


<!--#fsize file="foo.txt"-->
<!--#fsize virtual="/path_to/foo.txt"-->
<!--#config sizefmt="bytes"-->


The flastmod directive inserts the last modification date and time for a specified file. Valid arguments are the same as with the include command. The size of the file can be formatted using the timefmt parameter of the config command. The difference between the SSI environment variable LAST_MODIFIED and this command is that, flastmod allows you to choose any file, while LAST_MODIFIED displays the information for the current file.


<!--#flastmod file="foo.txt"-->
<!--#flastmod virtual="/path_to/foo.txt"-->

SSI Configuration

There are three things for SSI processing to work:

  1. Which directories have SSI's enabled.

  2. Whether exec is allowed from those directories.

  3. What file extension is used to tell the server to parse a file.

We now discuss these in detail using a UNIX-based server such as Apache (or NCSA) as reference; SSI's on Windows and Macintosh-based servers will be briefly discussed thereafter.

Directories : To Include or not to Include

In order to work, SSI's must be enabled at the server level. First, you should decide which directories you want to allow SSI's in. You may enable SSI's for the entire site or on a directory-by-directory basis. You may also configure the site to permit SSI's but prohibit the use of exec. Finally, you may activate SSI's for all files or only for files with a special file extension (usually shtml). Due to the system security issues associated with the SSI's, you need to be careful in your decision. Directories you do not trust, or aren't safe enough to use exec in, should be left out.

WHAT'S in a (File) Name?

Next, you need to tell the server what filename extension you are using for the parsed files. These files, though are similar to HTML, are thus not treated in the same manner. Internally, the server uses the MIME type text/x-server-parsed-html to identify parsed documents. It will then perform a format conversion to change these files into HTML for the client.

This is done from the information in the server configuration files. On the Apache server, this file is srm.conf. Similar configuration files are available on other servers. To tell the server which extension you want to use for parsed files, use the AddType directive. For example, the following line will force the server to parse all files that end in .shtml:

AddType text/x-server-parsed-html .shtml

(You can set the configuration so that the server parses all documents ending in html by doing the following:

AddType text/x-server-parsed-html .html

but this will sacrifice performance.) An important thing to note here is that you cannot have SSI directives within your CGI program, because the server does not parse the output generated by the program.

Type of SSI Directives

Now let's look at the two configuration options that you must set in the access configuration file (access.conf) that dictate what type of SSI directives you can place in your HTML document:

Here is how you would enable both Includes and Exec:

Options Includes ExecCGI

(On Apache, CGI can also be enabled using the ScriptAlias option.) To exclusively enable Includes without Exec, you need to add the following:

Options IncludesNoExec

Once again, prior to enabling either of these features, you should consider system security and performance.

To configure SSI's on a directory-by-directory basis, put the same directive in the .htaccess file of the directory where SSI's should be allowed.

Nested SSI's

Apache is currently configured in a manner that all files with the .shtml extension, even files included with SSI's, will be parsed by the server for SSI commands. If you want to include blocks of HTML code that will themselves contain other SSI commands, then you will have to give those files a .shtml extension.

SSI's on Windows and Macintosh-Based Servers

Many Windows-based WWW servers support SSI's. For example, SSI's are supported on Microsoft IIS and Netscape's FastTrack server for Windows NT 4.0. However, not all of them support the exec directive, and work quite differently than on a UNIX-based server. On Microsoft IIS, the server-parsed filenames need to have the extension .stm. Association of a Perl script with extension .pl with the Perl executable perl.exe seems to work only when the script is run in the DOS-mode. Furthermore, in order to execute it through the WWW browser, the association has to be defined in NT registry.

WebSTAR is one of the most widely-used WWW server on Macintoshes with a variety of features. It supports SSI's via "server-plug-in's". For details on extending the server to support SSI's, see the page on extending webstar.

Applications of SSI's

SSI's have a variety of applications. They allow users to create documents which provide dynamically generated information. Such information can include the current date, the file's last modification date, and the size or last modification of other files. In its more advanced usage, it can provide a powerful interface to CGI scripts and /bin/sh programs, which can be used to provide simple access counters or rotating banners.

Document Templates and Boilerplates

Visitors to a site are usually looking for the latest content. If they see a page that's out-of-date, they might ignore it or if they see a page without a date, they might assume it's out-of-date. Therefore, including the last modified date in a document is a good practice.

A useful application of SSI's is the automatic insertion of the date of the last modification of the document being requested. This is accomplished by inserting the following in the document:

<!--#echo var="LAST_MODIFIED"-->

in order to insert a date that appears like the following:

Friday, 09-May-99 09:34:18 EDT

This mimics a format of an HTTP header field. When looking at the information on last modification of a document, the time breakdown to seconds may not be of relevance to everybody. You can change the time format by including the following:

<!--#config timefmt="time-format"-->

before inserting the last modified date. time-format is a string compatible with the strftime(3) library function call under most versions of UNIX. This string consists of directives that begin with the percent symbol (%), as well as other characters.

<!--#config timefmt="%A, %B %d, %Y"-->

This should appear as:

Friday, May 9, 1999

In this example, %A is replaced with the day of the week, %B is replaced with the month, %d is replaced with the day of the month, and %Y is replaced with the year. Appendix II lists all the date and time formats you can use on a UNIX system; other operating systems might offer slightly different sets.

You can also insert the last modified date of other documents:

<!--#flastmod virtual="/path_to/foo.html"-->

This can be useful if you have an index or table of contents page which not only lists what documents are available, but also when were they last modified.

<TITLE>Table of Contents</TITLE>
<H1>Table of Contents</H1>
We have the following information for you:
  <LI>Document 1 (Last Modified : <PRE><!--#flastmod virtual="/path_to/1.html"--></PRE>)
  <LI>Document 2 (Last Modified : <PRE><!--#flastmod virtual="/path_to/2.html"--></PRE>)
<!--#echo var="LAST_MODIFIED"-->

Another application of SSI's is to provide identity and consistency to a site. This can be accomplished by creating document templates, and including repetitious pieces of information in them dynamically. Such examples include:

It is efficient to have these repetitious pieces of information stored in a file. These files to be included can be given the extension other than html (say incl) as these files contain HTML markup, but are not complete pages by themselves. By using file extensions as a key to a file content can help you keep better track of your files.

Now, using the SSI include directive, with the virtual parameter (so that we can put the included files anywhere in the site), we can create the desired (minimal) template:

<!--#include virtual="header.incl"-->
<!--#include virtual="footer.incl"-->

User Access Counter

SSI's can be quite useful for incorporating "CGI-like" information, as well as, output from CGI programs, into documents on the WWW. Using the SSI's with the exec cgi directive, you can embed the results of an entire CGI script into a static HTML document. We illustrate this via a user access counter example.

Suppose you have a simple CGI script (counter.cgi) on the server, that keeps track of the number of accesses by visitors to your site:

#!/path_to/perl -w

print "Content-type: text/plain", "\n\n";
$counter_file = "path_to/counter.txt";

open(FILE, ">>$counter_file");


open (FILE, "<" . $counter_file) || die "Can not read from the counter file.\n";
flock (FILE, 2);
$number_accesses = <FILE>;
flock (FILE, 8);
close (FILE);

open (FILE, ">" . $counter_file) || die "Can not write to the counter file.\n";
flock (FILE, 2);
print FILE $number_accesses;
flock (FILE, 8);
close (FILE);

print $number_accesses;

exit (0);

and a counter file counter.txt initialized to 0. The path_to Perl and the counter file in the above script should be configured for your system. Then, this counter script can be called by the execcgi command in an HTML document foo.shtml as:

This page has been accessed <!--#exec cgi="/cgi-bin/counter.cgi"--> times.

The process takes place as follows: whenever a user visits the document foo.shtml, the SSI command in it calls the script counter.cgi that reads the numerical value stored in counter data file counter.txt, increments it, writes the incremented value back to the file, and outputs it.

It should be noted that the above CGI counter script is for the purposes of illustration only. Since it does not use Perl's object-oriented techniques, it is portable across versions (Perl 4.036 and Perl 5) but it may suffer from weaknesses such as portability across platforms due to the use of flock function. For example, is not supported in latest release (Perl for Win32 Build 316) for Windows 95. The following alternative solutions are recommended:

  1. If you are using Apache, you could take advantage of the available counter modules (search the module registry database) and add one which suits your requirements. This solution is usually more efficient than using SSI's.

  2. There are also many freely (for non-commercial use and with restrictions on number of accesses per day) available public services (such as NedStat) that can give comprehensive analysis for pages that are registered with them.

  3. Counters on a page serve very little purpose. For comprehensive and more meaningful results, you can use one of the many freely available statistical programs (such as Analog which has ports for UNIX, Macintosh, and Windows) to analyze server log files, if you have requisite permissions to do so.

SSI Debugging

There are a few issues to keep in mind while using SSI's.

<!--echo var="REMOTE_USER"-->
<!-- #echo var="REMOTE_USER"-->

If you make either of these two mistakes, the server will not give you an error; rather it will treat the whole expression as an HTML comment.

Part II. Extended Server-Side Includes

XSSI's (eXtended Server-Side Includes) is part of Apache (version 1.2 and above) WWW server, and are an extension of (NCSA) SSI's. Apache contains an XSSI module, the module mod_include that defines a set of directives for that purpose.

Advantages of XSSI's

Apart of the inherent advantages of SSI's, there are some specific advantages of XSSI's:

XSSI Editing

The Webmonkey XSSI package extends the HTML editor Macromedia Dreamweaver 2.0, so you can use XSSI within the editor. The files provide a graphical interface for inserting and modifying XSSI commands. In addition, you can set environment variables to see what your page would look like in different conditions (such as with different browsers). Once the package is installed, XSSI directives can be inserted from the XSSI category of Dreamweaver's floating Objects palette.

Apache Module mod_include

This module is contained in the mod_include.c file, and is compiled by default.  You can use XSSI flow-control elements to set directives based on the user's environment variables. Several directives beyond the original NCSA definition were introduced in Apache 1.2, in particular, the new flow control directives.

In this part, we shall only discuss the additions to XSSI's beyond SSI's. For concepts common to both SSI's and XSSI's, we shall just provide a reference.

XSSI Environment Variables

Same as environment variables associated with SSI's.

XSSI Directives

An XSSI directive has the format:

<!--#command parameter=argument ... -->

The argument is usually enclosed in double quotes; many commands only allow a single parameter-argument pair. Note also that the comment terminator (-->) is preceded by whitespace.

XSSI's include all the directives in SSI's, with the following changes or additions.


The include directive with virtual parameter has been extended to include exec. So that you can use the following:

<!--#include virtual="/cgi-bin/bar/foo.cgi"-->

You can even add a query string to a CGI script called in this manner:

<!--#include virtual="/cgi-bin/bar/foo.cgi?query_string"-->

It is recommended that, the include virtual element should be used in preference to exec cgi.


This prints out a listing of all existing environment variables and their values. There are no parameters. An example is:

<!--#printenv -->

The output of above may look like:

HTTP_USER_AGENT = Mozilla/4.0 [en] (Win95; I)

The first part (in uppercase) is the name of the variable. The second part (after the equals sign) is its value.


This sets the value of a variable. The parameters are var, the name of the variable to set, and value, the value assigned to a variable. For example:

<!--#set var="some_variable" value="its_value" -->

sets a variable.


For example, suppose a document foo.shtml that has:

<!--#set var="size" value="$QUERY_STRING" -->
<FONT face="Verdana" size="<!--#echo var="size"
-->"><!--#echo var="QUERY_STRING" -->Text</FONT>

(Note that QUERY_STRING is a CGI environment variable available to XSSI's.) If you access foo.shtml as:


where n=1,2,3, and so on, you will see the size of "Text" change (if the browser supports the <FONT> tag. In a similar manner, you can change the other attributes of "Text" like the font face.

if, elif, else, endif

The flow-control directives allow you to make documents display differently depending on the variable.

<!--#if expr="test_condition" -->
<!--#elif expr="test_condition" -->
<!--#else -->
<!--#endif -->

The if command works like an if statement in a programming language. The test condition is evaluated and if the result is true, then the text until the next elif, else or endif command is included in the output stream. If the original test_condition is false, the elif or else statements are used to put text into the output stream. These commands are optional. The endif command ends the if command and is required.

The "test condition" is evaluated by Apache and, if it is true, the code following it is executed (if there are XSSI statements following it) or printed (if text/html follows it). The test_conditions possible are given in Table.

Test Condition xTruth Value Description


if string is not empty
string1 = string2
string1 != string2
string1 < string2
string1 <= string2
string1 > string2
string1 >= string2
  Compare string1 with string 2. If string2 has the form /string/ then it is compared as a regular expression (which have the same syntax as those found in the UNIX egrep command.)


if test_condition is true
! test_condition


if test_condition is false
test_condition1 && test_condition2


if both test_condition1 and test_condition2 are true
test_condition1 || test_condition2


if either test_condition1 or test_condition2 is true

Table. 2

"=" and "!=" have a precedence over "&&" and "||". "!" has the highest precedence. We shall see later a useful application of flow-control directives with some of the test_conditions given in Table 2.

Variable Substitution

In XSSI, the variable is referred to either simply by name, or with a preceding $ (in contexts where it is unclear as to whether it is a variable). Variable substitution is done within quoted strings in most cases where they may occur as an argument to an XSSI directive parameter. These include the echo, config, exec, flastmod, fsize, include, set, and flow-control directives.

The variables can be set in two different ways: you can set your own with the set command, or you can use one of the variables that is set automatically for each browser when it requests a page. (To see the list of such variables for a specific browser, you can use the <!--#printenv --> command.)

You can insert a $ sign into the string using a backslash preceding it, for example:

<!--#if expr="$x = \$test" -->


This example illustrates variable substitution in flow-control directives. It will print "in A" if the DOCUMENT_URI is /foo/file.html, "in B" if it is /bar/file.html and "in neither A or B" otherwise:

<!--#if expr="\"$DOCUMENT_URI\" = \"/foo/file.html\"" -->
in A
<!--#elif expr="\"$DOCUMENT_URI\" = \"/bar/file.html\"" -->
in B
<!--#else -->
in neither A or B
<!--#endif -->

XSSI Configuration

If documents containing XSSI directives are given the extension .shtml, the following directives will make Apache parse them and assign the resulting document the MIME type of text/html:

AddType text/html .shtml
AddHandler server-parsed .shtml

The following directive must be given for the directories containing the shtml files (usually in a <Directory> section, but this directive is also valid in .htaccess files if AllowOverride Options is set):

Options +Includes

The XBitHack Directive

There may be instances where you want to use XSSI's don't want to rename your pages from *.html to *.shtml. The XbitHack directive in Apache takes care of that. This directive only affects files associated with the MIME type text/html. All that is needed to have the server parse the page is to set the user-execute bit on.

In order to do this, you must add the following line to the .htaccess file:

XBitHack On

Now, any file that has the user-execute bit set will be treated as a server-parsed html document. So, if we set the appropriate file permissions (using chmod 744 in UNIX) on the file, the server will parse the page. (For security reasons, other files that are not being parsed should not be given these permissions.)

A potential problem with this method is that the file will be in fact executable. If you accidently run it from the command line, with all the characters "<" and ">" in it, you could ruin the entire site.

Applications of XSSI's

XSSI's extend the host of applications possible with SSI's. Some of these, such as serving host-specific pages (based on, say, browser is being used or the time of day), were previously possible only with languages such as JavaScript. In the next application, we undertake one such example.

Serving Host-Specific Pages

Using XSSI's flow-control directives, you can serve different pages based on user's domain name. As an example, you may want to serve specific pages when visitors come from three different places, and the same page for visitors coming from places other than these three:

You will first need to develop three documents, say, edu.incl, prof.incl, and gen.incl, corresponding to your educational experience, professional experience, and general information, respectively. You should put these in the same directory as your index.shtml page, which will include the XSSI's. In your index.shtml page, you should set up your title, and presentational elements (color, formating) that you desire. When someone makes a request for this page, it gets parsed on the server side, and a customized page gets served to the visitor without their knowledge.

For the XSSI's, you can customize your index.shtml based on the domain of your visitor: .uk for a visitor from UK, .gc.ca for a visitor from the Government of Canada, and .edu.au for a visitor from a University in Australia. You can use the REMOTE_HOST variable to test the domain name.

Now, you can include the following in your index.shtml:

<!--#if expr="\"$REMOTE_HOST\" = /.*uk/" -->
  <p><!--#include virtual="edu.incl" -->
<!--#elif expr="\"$REMOTE_HOST\" = /.*gc.ca/" -->
  <p><!--#include virtual="edu.incl" -->
  <p><!--#include virtual="prof.incl" -->
<!--#elif expr="\"$REMOTE_HOST\" = /.*edu.au/" -->
  <p><!--#include virtual="prof.incl" -->
<!--#else -->
  <p><!--#include virtual="gen.incl" -->
<!--#endif -->

The indentations are not necessary; they are included here to facilitate reading. The above example can be easily tailored. If you wish to serve the documents only in January for visitors from UK, in all months except in July for a visitor from the Government of Canada, without any time restrictions to visitors from a University in Australia or the user Einstein, and without any time restrictions elsewhere, you can do the following:

<!--#config timefmt="%B" -->

<!--#if expr="$DATE_GMT = /January$/ && \"$REMOTE_HOST\" = /.*uk/" -->
  <p><!--#include virtual="edu.incl" -->
<!--#elif expr="$DATE_GMT != /July$/ && \"$REMOTE_HOST\" = /.*gc.ca/" -->
  <p><!--#include virtual="edu.incl" -->
  <p><!--#include virtual="prof.incl" -->
<!--#elif expr="\"$REMOTE_HOST\" = /.*edu.au/ || \"$REMOTE_USER\" = /einstein/" -->
  <p><!--#include virtual="prof.incl" -->
<!--#else -->
  <p><!--#include virtual="gen.incl" -->
<!--#endif -->

XSSI Debugging

Besides those pointed in SSI's, there are a few more issues that you should keep under consideration:

<!--#printenv -->

The Transition to (X)SSI'S

Suppose we have a collection of HTML files in which we want to use the SSI technique. Then renaming these *.html files to *.shtml files becomes a daunting task. Using a Perl script (Perl Cookbook, By Tom Christiansen & Nathan Torkington, O'Reilly & Associates, 1998, p. 327.), this can be accomplished easily as follows:

Copy (though maintain the copyright) the following script to a file, call it rename and configure the path to Perl (#!/usr/bin/perl) for your system:

#!/usr/bin/perl -w
# rename - Larry's filename fixer
$op = shift or die "Usage: rename expr [files]\n";
chomp(@ARGV = <STDIN>) unless @ARGV;
for (@ARGV) {
  $was = $_;
  eval $op;
  die $@ if $@;
  rename($was,$_) unless $was eq $_;

On the shell prompt (for UNIX platforms; on other platforms a variant of find should work) type the following where the directory_name is the top level directory (with subdirectories where *.html files are residing):

find ./directory_name -name '*html' -print | rename 's/html/shtml/'


(X)SSI's are a very useful feature, but have their share of disadvantages.


In general, (X)SSI's can be costly for a server to continuously parse documents before sending them to the client. Specifically, as discussed before for SSI's, you can set the configuration so that the server parses all HTML documents (whether or not they have SSI directives). However, these can severely degrade system performance because the server has to parse all the HTML documents that it returns. Using exec directive can also at times be inefficient.


Use of the exec directive can be a potential security risk. It is considered a security risk to have average users executing commands as the server's "User". Novice users could possibly embed directives to execute system commands that output confidential information. exec can also be used to attack the security of a site.

For example, say you have an SSI-enabled guestbook script on a server that allows visitors to enter HTML code as part of their comments. If the script does not filter out SSI directives from input, then entering the following:

<--#exec cmd="/bin/rm -fr /"-->

in a form field can pose a serious problem. Similarly, a careless assignment of file permissions while using the XSSI XBitHack directive, can lead to various problems.

You should consider these items carefully before activating (X)SSI's on your server. Despite these shortcomings, (X)SSI's can be a very powerful tool if used cautiously.


Someday, we will all script this way

(X)SSI's are useful alternative to CGI, and in some cases to JavaScript, for carrying out routine tasks. They offer various advantages, particularly for large-scale site management, if deployed judiciously, and with caution.

For any serious user, official references to the NCSA (for SSI's) and Apache (XSSI's) documentation (see the list of references) are a must.

Some alternatives to (X)SSI's themselves are discussed in Appendix III.


Appendix I : SSI Directives

Command Parameter Description
config   Modifies various aspects of SSI
errmsg   Default error message
sizefmt Format for size of the file
timefmt  Format for dates
echo var Inserts value of special SSI variables as well as other environment variables
exec   Executes external programs and inserts output in current document
cmd      Any application on the host
cgi    CGI program
flastmod file  Inserts the last modification date and time for a specified file
fsize     file   Inserts the size of a specified file
include   Inserts text of document into current file
file   Pathname relative to current directory
virtual  Virtual path to a document on the server

Table. 3

Appendix II : SSI Time Formats







Day of the week abbreviation Sun (for Sunday)


Day of the week Sunday


Month name abbreviation Mar (for Mar)


Month name March


The day of the month as a decimal number (see note below) 1 (not 01)


Date as mm/dd/yy  (or %m/%d/%y) 06/23/95


Date of the month as a decimal number in a two-digitfield ranging from 1 through 31 (see note below) 01


The hour of the 24-hour clock as a decimal number (00 through 23) 13


The hour of the 12-hour clock as a decimal number (00 through 12) 1


The day of the year as a decimal number (01 through 366) 111


The month of the year as a decimal number (01 through 12) 11


The minutes of the hour as a decimal number (00 through 59) 08


The local AM or PM string p.m.


The 12-hour clock time in local AM/PM notation Time as "%I:%M:%S AM | PM"    10:24:58 AM


The seconds of the minute as a decimal number (00 through 59) 50


The 24-hour time in "%H:%M:%S" format (see note below) 16:23:43


The week of the year as a decimal number (00 through 52) with Sunday as the first day of the week Week of the year (also %W) 49


The day of the week as a decimal number (0 through 6) 05


The week of the year (00 through 53) with Monday as the first day of the week 50


The year of the century (00 to 99) 99


Year as a decimal number 1999


The time zone name (if one can be determined) EST

Table. 4

Jukka Korpela reports:

I noticed that on a server that I run for testing purposes (a poor old OmniHTTPd), %e and %T did not work at all. Well, that was a software limitation, but then I realized that what %e should mean is not what this appendix says, namely "Date of the month as a decimal number in a two-digitfield ranging from 1 through 31", but (according to strftime documentation at http://www.unix-systems.org/online.html) "day of the month as a decimal number [1,31]; a single digit is preceded by a space". So it seems that the appendix has got %d and %e reversed!

Appendix III : Other Solutions

Beyond (X)SSI's, there are ongoing efforts towards introducing the idea of more powerful parsed HTML which includes commands to be read and executed by an engine before a Web page is delivered. Notable approaches include:

Related items

CGI Security : Better Safe than Sorry

Creating a Page Counter In Perl

Speed Thrills : CGI Please ... and Fast!

CGI Programming Made (Relatively) Easy Using Libraries

Random and Recursive Crypting using Salt on Unix and Win32

Timestamping an HTML Document

Deleting Files in Perl

Creating a mailing list using Perl

Reading and Writing to Files on the Server

Server Side Includes and CGI Security

Feedback on 'Server-Side Includes and its Extensions'

©2018 Martin Webb