path: root/SECURITY
diff options
Diffstat (limited to 'SECURITY')
1 files changed, 131 insertions, 0 deletions
diff --git a/SECURITY b/SECURITY
new file mode 100644
index 0000000..098f124
--- /dev/null
@@ -0,0 +1,131 @@
+Background: Every few months CERT announces Yet Another Security Hole In
+Sendmail---something that lets local or even remote users take complete
+control of the machine. I'm sure there are many more holes waiting to be
+discovered; sendmail's design means that any minor bug in 46000 lines of
+code is a major security risk. Other popular mailers, such as Smail, and
+even mailing-list managers, such as Majordomo, seem nearly as bad.
+Note added in 1998: I wrote the above paragraph in December 1995, when
+the latest version of sendmail was 8.6.12 (with 41000 lines of code).
+Fourteen security holes were discovered from sendmail 8.6.12 through
+8.8.5. See
+I started working on qmail because I was sick of this cycle of doom.
+Here are some of the things I did to make sure that qmail will never let
+an intruder into your machine.
+1. Programs and files are not addresses. Don't treat them as addresses.
+sendmail treats programs and files as addresses. Obviously random people
+can't be allowed to execute arbitrary programs or write to arbitrary
+files, so sendmail goes through horrendous contortions trying to keep
+track of whether a local user was ``responsible'' for an address. This
+has proven to be an unmitigated disaster.
+In qmail, programs and files are not addresses. The local delivery
+agent, qmail-local, can run programs or write to files as directed by
+~user/.qmail, but it's always running as that user. (The notion of
+``user'' is configurable, but root is never a user. To prevent silly
+mistakes, qmail-local makes sure that neither ~user nor ~user/.qmail is
+group-writable or world-writable.)
+Security impact: .qmail, like .cshrc and .exrc and various other files,
+means that anyone who can write arbitrary files as a user can execute
+arbitrary programs as that user. That's it.
+2. Do as little as possible in setuid programs.
+A setuid program must operate in a very dangerous environment: a user is
+under complete control of its fds, args, environ, cwd, tty, rlimits,
+timers, signals, and more. Even worse, the list of controlled items
+varies from one vendor's UNIX to the next, so it is very difficult to
+write portable code that cleans up everything.
+Of the twenty most recent sendmail security holes, eleven worked only
+because the entire sendmail system is setuid.
+Only one qmail program is setuid: qmail-queue. Its only purpose is to
+add a new mail message to the outgoing queue.
+3. Do as little as possible as root.
+The entire sendmail system runs as root, so there's no way that its
+mistakes can be caught by the operating system's built-in protections.
+In contrast, only two qmail programs, qmail-start and qmail-lspawn,
+run as root.
+4. Move separate functions into mutually untrusting programs.
+Five of the qmail programs---qmail-smtpd, qmail-send, qmail-rspawn,
+qmail-remote, and tcp-env---are not security-critical. Even if all of
+these programs are completely compromised, so that an intruder has
+control over the qmaild, qmails, and qmailr accounts and the mail queue,
+he still can't take over your system. None of the other programs trust
+the results from these five.
+In fact, these programs don't even trust each other. They are in three
+groups: tcp-env and qmail-smtpd, which run as qmaild; qmail-rspawn and
+qmail-remote, which run as qmailr; and qmail-send, the queue manager,
+which runs as qmails. Each group is immune from attacks by the others.
+(From root's point of view, as long as root doesn't send any mail, only
+qmail-start and qmail-lspawn are security-critical. They don't write any
+files or start any other programs as root.)
+5. Don't parse.
+I have discovered that there are two types of command interfaces in the
+world of computing: good interfaces and user interfaces.
+The essence of user interfaces is _parsing_---converting an unstructured
+sequence of commands, in a format usually determined more by psychology
+than by solid engineering, into structured data.
+When another programmer wants to talk to a user interface, he has to
+_quote_: convert his structured data into an unstructured sequence of
+commands that the parser will, he hopes, convert back into the original
+structured data.
+This situation is a recipe for disaster. The parser often has bugs: it
+fails to handle some inputs according to the documented interface. The
+quoter often has bugs: it produces outputs that do not have the right
+meaning. Only on rare joyous occasions does it happen that the parser
+and the quoter both misinterpret the interface in the same way.
+When the original data is controlled by a malicious user, many of these
+bugs translate into security holes. Some examples: the Linux login
+-froot security hole; the classic find | xargs rm security hole; the
+Majordomo injection security hole. Even a simple parser like getopt is
+complicated enough for people to screw up the quoting.
+In qmail, all the internal file structures are incredibly simple: text0
+lines beginning with single-character commands. (text0 format means that
+lines are separated by a 0 byte instead of line feed.) The program-level
+interfaces don't take options.
+All the complexity of parsing RFC 822 address lists and rewriting
+headers is in the qmail-inject program, which runs without privileges
+and is essentially part of the UA.
+6. Keep it simple, stupid.
+See BLURB for some of the reasons that qmail is so much smaller than
+sendmail. There's nothing inherently complicated about writing a mailer.
+(Except RFC 822 support; but that's only in qmail-inject.) Security
+holes can't show up in features that don't exist.
+7. Write bug-free code.
+I've mostly given up on the standard C library. Many of its facilities,
+particularly stdio, seem designed to encourage bugs. A big chunk of
+qmail is stolen from a basic C library that I've been developing for
+several years for a variety of applications. The stralloc concept and
+getln() make it very easy to avoid buffer overruns, memory leaks, and
+artificial line length limits.