In any software product as large and complex as gopher there is the possibility of security holes. In this paper we'll show
you what they are and how to run a secure gopher server, gopher client, and gopher public access system.
April 18, 1994
1.0 Introduction
Gopher has had its small share of security problems. The
University of Minnesota, in conjunction with CERT and
other computer security agencies attempts to keep the
Gopher software as secure as it possibly can.
Now that the gopher software is installed on thousands of
sites it is imperative that all holes be documented and
fixed. We believe that release 1.13 and 2.013 are free of
security holes and that you should upgrade to these
releases as soon as possible.
We make no claims as the security or insecurity of other
software. This paper only applies to the Unix/VMS
Gopher Software released by the University of Minnesota.
2.0 The Origin of Holes
There are a few programming practices and design deci-
sions that have caused most of the holes in gopher soft-
ware. These practices pervade other software packages
too.
2.1 Use of software routines to insure security.
The most popular method of maintaining a secure environ-
ment is to use the chroot() system call to change the loca-
tion of the / directory to a subdirectory. This is the method
used by most FTP servers. Consider the following code
snippet:
chroot("/usr/local/gopher-data");
This code causes the program to instantly think
/usr/local/gopher-data
is the slash directory. Thus if you try to access /etc/passwd
you will, in fact, be attempting to access
/usr/local/gopher-data/etc/passwd
There are a couple of problems with this scheme however.
The first is that you need root privileges to use this system
call. Also, sometimes you want to access files that aren't in
your gopher-data directory. For instance you might want
to make a symbolic link to your manual pages like this:
The solution to both of these problems was contributed by
John Sellins from the University of Waterloo.
Instead of relying on the chroot() system call, a suite of
software routines were written to insure that all requests
are legitimate. The routines strip out all occurrences of `..'
in gopher requests and append the server data directory to
certain requests. If these checks weren't in place a cracker
could do this:
0/../../../../../../../../../../etc/passwd
This request would retrieve the password file of the system
running the gopher server if it wasn't for the dot stripping
routines.
Our example of a symbolic link works however, since
there aren't any `..' character strings in the request.
As we'll see later, bugs and oversights in this section of
code have caused security holes.
2.2 Use of Dangerous Routines in the Server
and Client
The server and client use two highly dangerous routines to
implement portions of the code. These calls are system()
and popen(). The server uses this code to decompress files
on the fly and run shell scripts to perform functions not
implemented in the server. The client uses these routines
to execute `helper' applications to send email, invoke tele-
communications download protocols and display many
data types.
The problem with both of these calls is that they use the
shell `sh' to evaluate the expression sent to them. The shell
has a very extensive feature set that makes it difficult to
ensure security through software routines. It's possible for
a malicious user to exploit these weaknesses to actually
run commands on the server. For instance the gopher
server has a special notation for running an external shell
script. Here's an example:
exec:arg1 arg2:/bin/legisearch
In this case the server executes:
popen("/bin/legisearch arg1 arg2");
which in turn executes:
sh -c "/bin/legisearch arg1 arg2"
In earlier versions of the server a malicious user could
send the following command to a server running with the
`-c' (non-chroot) option:
exec:arg1 ;cat /etc/passwd:/bin/legisearch
The server then would then execute:
sh -c "/bin/legisearch arg1 ;cat /etc/passwd"
The semicolon (;) tells the shell to execute a second com-
mand and add the results to that of the first. In this case the
command prints out the contents of the Unix password
file.
This problem will only occur if you have shell scripts on
your server (the software will not execute non-existent
shell scripts.) If you're using the default chroot() mode a
cracker won't be able to get at files outside of the gopher
directory tree. However, they could still wreak major dam-
age to your gopher data.
This problem of hidden code execution plagued earlier
versions of the client as well. The Gopher client allows
connections to telnet sites by launching the telnet com-
mand with the name of a host. It does this by using the sys-
tem() system call like this:
system("telnet pubinfo.ais.umn.edu");
However if an unscrupulous server administrator created a
bogus telnet item with a hostname like this:
"pubinfo.ais.umn.edu;echo + >.rhosts"
This would cause the .rhosts file of the person using the
client to be compromised when they selected the item.
Gopher links like this are `telnet bombs' just waiting to be
opened, much like physical mail bombs.
Starting with release 2.0.12 we've started replacing these
routines with more general secure code that does not use
the shell. So far we've converted most of the client side
and some of the server calls. Eventually we will be rid of
this problem altogether.
3.0 Known Holes
Here is a list of the known holes in gopher and gopherd for
Unix system. It is probably not complete.
· All releases between 0.9 and 1.12 and 2.0 to 2.04 may
allow executing external commands with the exec:
facility.
· All releases between 2.0 and 2.012 and before 1.13
may allow `telnet bombs'.
· Releases before 2.0.12 had dedot routines that could be
tricked with the right combination of quotes and dots.
4.0 Known Bad Practices
These aren't holes really, but they are things that people do
that could prove very, very dangerous..
Some sites allow simultaneous ftp and gopher access to
the same set of files. Often a directory will be writable for
uploads for ftp users. If the execute bit is turned on for
uploads the cracker could upload shell scripts to the server,
which could then be activated by a gopher client.
5.0 Insuring Security of the Gopher
Server
Even with the potential for security holes it is still possible
to run a secure gopher server. The following steps are
insurance against future security holes.
The safest thing in any circumstances is to not run the
server at all. If you are very security conscious you may
not want to trust your data to software that doesn't come
with a warranty.
However this is short sited at best. There are a number of
techniques to make your gopher server secure.
· Avoid the chroot() (-c) option if you can. This is per-
haps the most dangerous portion of the gopher code.
It's been gone over with a fine tooth comb, but there's
no guarantee that we've closed every loophole.
· Always, always, always run the server as a non-root
user i.d. The server has a -u parameter to set the user-
name. Use it! Any damage that a user can cause can be
minimized by running as a non privileged user.
· Be careful with shell scripts. The gopher server can't
save you from shooting yourself in the foot by using a
poorly written, insecure shell script.
· Always log your transactions! Use the -l option of
gopherd to specify a log file like this.
-l /usr/adm/gopherlog
This will give you an audit trail in case anything hap-
pens. It also gives you a way to find anomalies in
access. A log analyzer will be able to tell you if you're
receiving a disproportionate number of connections
from certain sites
· If your server contains sensitive information you may
want to use the ip/hostname security option of the
server. This is done by using `access:' lines in your
gopherd.conf configuration file.
The following lines will allow only hosts from the Uni-
versity of Minnesota to access your server. Note that
this style of security has some obscure holes. If your
DNS server is compromised, then so is your gopher
server if it uses this form of authentication.
access: default !read,!browse,!search,!ftp
access: .umn.edu read,browse,search,ftp
· Consider executing your scripts with `taintperl'. This
version of perl makes sure that you never use user
input to execute a command on your system.
6.0 Insuring the Security of Your Client
The client is less problematic that the server, but it still has
it's own problems.
· Upgrade to 2.013 or higher. Earlier versions could
potentially execute a `telnet bomb'. If you read the
warning screen you'll probably notice it, but you could
easily miss it.
· Certain file types are inherently insecure. You should
trust the source of postscript and Microsoft Word docu-
ments before viewing them. Both systems can execute
system macros that could alter data and files on your
system. This is not a gopher problem, but a general
information retrieval problem. Other file formats can
potentially cause the same problems.
7.0 Insuring the Security of Your Public
Access Client
A public access client allows people to connect to the
internet, (often without a password) and use a gopher cli-
ent. This allows dial up users and those without the
resources to run a gopher client on their own system
access to the gopher network. A public access client can
be an enormous security risk if not installed properly. The
following steps should give you a secure public access cli-
ent, but again, we make no guarantees.
The first step is to create the home directory of the for the
guest account. This directory should not be writable nor
owned by the guest account.
In this directory you will want to place a shell script that
will start the gopher client automatically. Here is an exam-
ple:
Note that we set the path to a bin directory inside of the
guest account directory. We want to insure that only pro-
grams inside of this directory are run. The reason we do
this is that many programs allow you to get to a shell, like
telnet, tn3270, less, more and many others. You should put
secure versions of these programs in the bin directory
inside the guest directory.
Also note that we use the -s option for gopher. This
invokes the `secure' option of the client. In this mode the
client won't let you save or print.
Finally you can create the guest account. Make sure that
the shell is specified as the script. Don't put /bin/csh or /
bin/sh for the shell. Here's an example entry for a guest
account: