diff options
| author | manuel <manuel@mausz.at> | 2013-02-04 00:08:53 +0100 |
|---|---|---|
| committer | manuel <manuel@mausz.at> | 2013-02-04 00:08:53 +0100 |
| commit | 69aec538b456402170dc723af417ba5c05389c32 (patch) | |
| tree | e6f34c543f17c6392447ea337b2e2868212424d1 /SECURITY | |
| download | qmail-69aec538b456402170dc723af417ba5c05389c32.tar.gz qmail-69aec538b456402170dc723af417ba5c05389c32.tar.bz2 qmail-69aec538b456402170dc723af417ba5c05389c32.zip | |
qmail 1.03 import
Diffstat (limited to 'SECURITY')
| -rw-r--r-- | SECURITY | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/SECURITY b/SECURITY new file mode 100644 index 0000000..098f124 --- /dev/null +++ b/SECURITY | |||
| @@ -0,0 +1,131 @@ | |||
| 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 http://pobox.com/~djb/docs/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 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. | ||
