SLAC's CGI Script Security Wrapper Implementation
Last Update: March 8, 1996
SLAC, the Lab |
This page and the SLAC CGI Script Security Wrapper are
still in development.
The SLAC CGI script security Wrapper is implemented by a REXX script called
cgi-wrap. The purpose of cgi-wrap is to
provide the WWW server (www.slac.stanford.edu)
with a security wrapper. This allows the server to execute a selected set of
commands, while imposing some security constraints. The selection
of commands that are authorized to be executed by cgi-wrap are determined
by a Rules file. All input passed to cgi-wrap
is reviewed for possible security concerns and also passed on
unmodified to the command to be executed.
cgi-wrap [-td] [auth=user] command
command is a reference to a Unix type command or user
script. Command will be used by cgi-wrap to
look up in the Rules file to see whether the command exists
and if so to execute the relevant command.
user, if provided, tells cgi-wrap to look up
what Rules file is to be used. The default is to use
- If the environment variable REQUEST_METHOD="POST" then
standard input is read into a local variable Cmd. It is
also saved unmodified in a temporary file so it can be passed as standard
input onto the command that is eventually executed.
- Input from the environment variables PATH_INFO and
QUERY_INPUT are then read and stored in Cmd.
- Any question mark (?), backslash (\) or plus sign (+)
in the Cmd is converted to a space.
- Any occurences of %2B (or %2b), %20, or %2F (or %2f)
are converted to a plus sign (+),
or space, or foward slash (/) respectively.
Next the options are processed, followed by looking for the
location of the Rules file if "auth=user" appears in
the command. The user, if provided, is used to look in the file
/u/sf/cottrell/lib/qcmd.users for the actual file to be used for
the rules. If no "auth=user" is provided, then
the default Rules file is /u/sf/cottrell/lib/qcmd.list.
If the command line starts with the string "WRAP" or "wrap"
then the input is presumed to come from an HTML form and the
name=value& clauses in Cmd are turned into
name value pairs.
Any remaining ampersands (&) are then converted to spaces.
Rules file is then searched for
"command" in the
first token of each line. If it is found then the actual command to be
executed, together with restrictions are extract from the line. Otherwise
a diagnostic is issued and cgi-wrap exits.
If the restrictions indicate the command is only allowed
to be executed if the client is in the SLAC domain (134.79.) then
the environment variable REMOTE_ADDR is checked to
ensure the client is in the SLAC domain. If not a diagnostic
is issued and cgi-wrap exits.
The text in Cmd is then verified to ensure that the characters only include
" [0-9] [a-z] [A-Z] -_/.@+" (where the  are metacharacters
indicating a range of characters, and the double quotes (") are not included
in the acceptable characters) with the addition of % if this is specified
in the restrictions.
If this is not the case cgi-wrap issues a
diagnostic and exits.
If the restrictions indicate that the user's script will not provide
a MIME "Content-type: type/subtype" then cgi-wrap
provides "Content-type: text/html" and also looks to see if
the user's script will provide a "<title>".
If the restrictions indicate that command line
arguments are allowed for the command
then the arguments provided in the input are placed in the appropriate place
in the output command.
If the restrictions indicate that the command is to be executed
in only the TEST server, then cgi-wrap looks at the
SERVER_NAME and SERVER_PORT environment variables to
check that it is running in www.slac.stanford.edu:5080. If this
is not the case then cgi-wrap issues a diagnostic and exits.
The specified command is then checked to see if it has an embedded pipe (|)
in it. If it does then it is executed via ADDRESS UNIX. If not it
calls a Perl script wrap_timeout which with
a timeout of 5 minutes, executes the command. If the command is
not completed in the timeout, then wrap_command will kill
the process group. In either case (with or without the pipe) the command is
executed with the original standard input being piped to it, and
the original environment variables untouched by cgi-wrap.