nightmaremail

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

SECURITY.md (6009B)


      1 Background: Every few months CERT announces Yet Another Security Hole In
      2 Sendmail -- something that lets local or even remote users take complete
      3 control of the machine. I'm sure there are many more holes waiting to be
      4 discovered; sendmail's design means that any minor bug in 46000 lines of
      5 code is a major security risk. Other popular mailers, such as Smail, and
      6 even mailing-list managers, such as Majordomo, seem nearly as bad.
      7 
      8 Note added in 1998: I wrote the above paragraph in December 1995, when
      9 the latest version of sendmail was 8.6.12 (with 41000 lines of code).
     10 Fourteen security holes were discovered from sendmail 8.6.12 through
     11 8.8.5. See <https://cr.yp.to/maildisasters/sendmail.html>.
     12 
     13 I started working on qmail because I was sick of this cycle of doom.
     14 Here are some of the things I did to make sure that qmail will never let
     15 an intruder into your machine.
     16 
     17 
     18 1. Programs and files are not addresses. Don't treat them as addresses.
     19 
     20 sendmail treats programs and files as addresses. Obviously random people
     21 can't be allowed to execute arbitrary programs or write to arbitrary
     22 files, so sendmail goes through horrendous contortions trying to keep
     23 track of whether a local user was "responsible" for an address. This
     24 has proven to be an unmitigated disaster.
     25 
     26 In qmail, programs and files are not addresses. The local delivery
     27 agent, qmail-local, can run programs or write to files as directed by
     28 ~user/.qmail, but it's always running as that user. (The notion of
     29 "user" is configurable, but root is never a user. To prevent silly
     30 mistakes, qmail-local makes sure that neither ~user nor ~user/.qmail is
     31 group-writable or world-writable.)
     32 
     33 Security impact: .qmail, like .cshrc and .exrc and various other files,
     34 means that anyone who can write arbitrary files as a user can execute
     35 arbitrary programs as that user. That's it.
     36 
     37 
     38 2. Do as little as possible in setuid programs.
     39 
     40 A setuid program must operate in a very dangerous environment: a user is
     41 under complete control of its fds, args, environ, cwd, tty, rlimits,
     42 timers, signals, and more. Even worse, the list of controlled items
     43 varies from one vendor's UNIX to the next, so it is very difficult to
     44 write portable code that cleans up everything.
     45 
     46 Of the twenty most recent sendmail security holes, eleven worked only
     47 because the entire sendmail system is setuid.
     48 
     49 Only one qmail program is setuid: qmail-queue. Its only purpose is to
     50 add a new mail message to the outgoing queue.
     51 
     52 
     53 3. Do as little as possible as root.
     54 
     55 The entire sendmail system runs as root, so there's no way that its
     56 mistakes can be caught by the operating system's built-in protections.
     57 In contrast, only two qmail programs, qmail-start and qmail-lspawn,
     58 run as root.
     59 
     60 
     61 4. Move separate functions into mutually untrusting programs.
     62 
     63 Five of the qmail programs -- qmail-smtpd, qmail-send, qmail-rspawn,
     64 qmail-remote, and tcp-env -- are not security-critical. Even if all of
     65 these programs are completely compromised, so that an intruder has
     66 control over the qmaild, qmails, and qmailr accounts and the mail queue,
     67 he still can't take over your system. None of the other programs trust
     68 the results from these five.
     69 
     70 In fact, these programs don't even trust each other. They are in three
     71 groups: tcp-env and qmail-smtpd, which run as qmaild; qmail-rspawn and
     72 qmail-remote, which run as qmailr; and qmail-send, the queue manager,
     73 which runs as qmails. Each group is immune from attacks by the others.
     74 
     75 (From root's point of view, as long as root doesn't send any mail, only
     76 qmail-start and qmail-lspawn are security-critical. They don't write any
     77 files or start any other programs as root.)
     78 
     79 
     80 5. Don't parse.
     81 
     82 I have discovered that there are two types of command interfaces in the
     83 world of computing: good interfaces and user interfaces.
     84 
     85 The essence of user interfaces is _parsing_ -- converting an unstructured
     86 sequence of commands, in a format usually determined more by psychology
     87 than by solid engineering, into structured data.
     88 
     89 When another programmer wants to talk to a user interface, he has to
     90 _quote_: convert his structured data into an unstructured sequence of
     91 commands that the parser will, he hopes, convert back into the original
     92 structured data.
     93 
     94 This situation is a recipe for disaster. The parser often has bugs: it
     95 fails to handle some inputs according to the documented interface. The
     96 quoter often has bugs: it produces outputs that do not have the right
     97 meaning. Only on rare joyous occasions does it happen that the parser
     98 and the quoter both misinterpret the interface in the same way.
     99 
    100 When the original data is controlled by a malicious user, many of these
    101 bugs translate into security holes. Some examples: the Linux login
    102 -froot security hole; the classic find | xargs rm security hole; the
    103 Majordomo injection security hole. Even a simple parser like getopt is
    104 complicated enough for people to screw up the quoting.
    105 
    106 In qmail, all the internal file structures are incredibly simple: text0
    107 lines beginning with single-character commands. (text0 format means that
    108 lines are separated by a 0 byte instead of line feed.) The program-level
    109 interfaces don't take options.
    110 
    111 All the complexity of parsing RFC 822 address lists and rewriting
    112 headers is in the qmail-inject program, which runs without privileges
    113 and is essentially part of the UA.
    114 
    115 
    116 6. Keep it simple, stupid.
    117 
    118 See BLURB.md for some of the reasons that qmail is so much smaller than
    119 sendmail. There's nothing inherently complicated about writing a mailer.
    120 (Except RFC 822 support; but that's only in qmail-inject.) Security
    121 holes can't show up in features that don't exist. 
    122 
    123 
    124 7. Write bug-free code.
    125 
    126 I've mostly given up on the standard C library. Many of its facilities,
    127 particularly stdio, seem designed to encourage bugs. A big chunk of
    128 qmail is stolen from a basic C library that I've been developing for
    129 several years for a variety of applications. The stralloc concept and
    130 getln() make it very easy to avoid buffer overruns, memory leaks, and
    131 artificial line length limits.