1                               SqWebMail security
2
3   This document discloses security-oriented issues regarding the SqWebMail
4   CGI application.
5
6   In this document:
7
8     * [1]User IDs and Passwords
9     * [2]Mailbox IDs
10     * [3]Authentication
11     * [4]Browser Security - History
12     * [5]Browser Security - Caching
13     * [6]Browser Security - HTML
14     * [7]Browser Security - Referer: Tags
15     * [8]Sending Mail
16     * [9]Setuid Root
17
18User IDs and Passwords
19
20   SqWebMail's security scheme requires a valid userid/password to access an
21   account. The actual method for validating the userid and password is a
22   black-box module that can be easily replaced. The example black-box
23   implementation uses the PAM library, if available, or with the
24   /etc/passwd, /etc/shadow and the crypt() function.
25
26   It is possible to configure SqWebMail to transmit the userid and password
27   via secure HTTP. If secure HTTP is not available, the userid and password
28   is transmitted over the network in the clear, which can be picked up by a
29   sniffer.
30
31Mailbox IDs
32
33   After a userid and password is authenticated, the authentication module
34   returns a 'mailboxid'. The mailboxid is used as a handle for the mailbox.
35   A mailboxid may not necessarily be the same as the userid, but the sample
36   authentication modules make them the same.
37
38   Technically, the mailboxid that's generated by recent versions of
39   sqwebmail are of the form "userid.method", where method represents the
40   authentication module that was used.
41
42   A mailboxid is sent with every HTTP request, in the request itself. Note
43   that the mailboxid is transmitted over the network in the clear. It is
44   also possible to use secure HTTP for the every HTTP request, not just
45   initial authentication, but this has not been tested.
46
47   Unless the mailboxid is the same as a userid, there aren't many security
48   considerations in having the mailboxid broadcasted over the network.
49   That's because the mailboxid in the HTTP request is usually validated
50   based on a time-limited IP address (see "[10]Authentication"). Note that
51   there certain other potential ways - in addition to network traffic
52   sniffing - for an unauthorized party to attempt to grab mailboxids. See
53   "[11]Browser Security - HTML", and "[12]Browser Security - Referrer:
54   Tags".
55
56Authentication
57
58   Once the user ID and password are authenticated, authentication for
59   subsequent HTTP requests is based on a combination of an IP address, plus
60   a 128-bit random number that was generated during the login.
61
62   By default, SqWebMail permits access to the mailbox only from the same IP
63   address as the one where the user ID and password was authenticated from.
64   This can be selectively turned off at login time, in cases where the
65   client is behind a load-balancing firewall that uses multiple IP
66   addresses. In all cases, a 128-bit random number must be transmitted with
67   every HTTP request, and it must match the number generated during the
68   login, which is saved in the Maildir directory.
69
70   The Maildir directory must therefore have any group or world access rights
71   disabled. Additionally, every page served by SqWebMail includes HTTP
72   headers containing instructions to proxies and browsers that prohibit this
73   page from being cached. There are some buggy web browsers out there - most
74   of them originating in Redmond,WA - that ignore these caching directives,
75   and they end up saving the 128-bit random number in the local cache.
76   Unless access to the physical machine is secured, the local cache can be
77   trawled to obtain the 128-bit authentication token.
78
79   However, access to the mailbox is allowed only for a maximum period of
80   time after the initial authentication. Access is allowed only if the HTTP
81   requests come within a different, shorter period of time. If no access
82   requests have been made for a certain period of time, access will no
83   longer be available even if it comes from the right IP address, with the
84   right authentication token.
85
86   The IP address of the initial authentication, the dates and times
87   involved, are all stored in files in the maildir directory, with group and
88   world permissions turned off.
89
90Browser Security - History
91
92   In certain situations a mailboxid is a part of the actual URL requested. A
93   browser may maintain a history file of visited URLs.
94
95   SqWebMail uses a frame window in an attempt to keep the browser from
96   recording visited URLs. This approach works for most popular web browsers
97   that support frames - these browsers do not maintain history for
98   individual frames. Note that frames are not required to access the full
99   SqWebMail functionality.
100
101Browser Security - Caching
102
103   SqWebMail sets the expiration header on every HTTP page it serves.
104   Individual pages contain URLs and hidden fields with mailboxids. The
105   expiration header should keep the web pages from being saved in the
106   browser cache.
107
108Browser Security - HTML
109
110   SqWebMail has the ability to display HTML E-mail, which leads to several
111   complicated situations regarding embedded Javascript or Java applets that
112   try to grab the mailboxid of the recipient (amongst other things).
113   SqWebMail attempts to remove all forms of scripting from HTML E-mail as
114   follows:
115
116     * The following HTML tags are removed: <SCRIPT>, </SCRIPT>, <APP>,
117       </APP>, <APPLET>, </APPLET>, <SERVER>, </SERVER>, <OBJECT>, </OBJECT>,
118       <HTML>, </HTML>, <HEAD>, </HEAD>, <BODY>, </BODY>, <META>, <TITLE>,
119       </TITLE>, <FRAME>, </FRAME>, <LINK>, <IFRAME> and </IFRAME>.
120     * The following HTML attributes are stripped from every tag: ONLOAD=,
121       ONMOUSEOVER=, and all ON*= attributes; BACKGROUND=, STYLE=, TARGET=,
122       CODE=, CODETYPE=, and LANGUAGE= are removed; TARGET=_blank is added to
123       all <A> tags.
124     * The HREF and SRC attributes are stripped, unless the URL starts with
125       one of the following: http:, https:, ftp:, gopher:, wais:, or telnet,
126       and cid:.
127     * The HREF and SRC attribute values are prefixed with a URL that will
128       resolve to SqWebMail, and with an additional TARGET="_blank"
129       attribute. A request to that resulting URL will result in a blank page
130       with a 0-second refresh to the original URL. This method strips
131       mailbox IDs from Referer: tags sent to external web site. If the HREF
132       attribute starts with a cid:, it is replaced by an http: reference to
133       SqWebMail that will return the specified MIME part.
134     * IMG tags are removed and replaced with an A tag, in order to keep the
135       HTTP client from automatically loading any images from external web
136       sites, upon opening a given message.
137     * Everything inside the STYLE tag is removed.
138
139Browser Security - Referer: Tags
140
141   See the previous section regarding how SqWebMail attempts to remove
142   mailbox IDs from Referer: tags.
143
144Sending Mail
145
146   SqWebMail includes the ability to send mail. Issues regarding transmitting
147   E-mail from the HTTP client to the server are obvious. SqWebMail runs a
148   wrapper shell script in order to send the E-mail message. The wrapper
149   shell script normally runs qmail-inject, sendmail, or something else,
150   immediately. SqWebMail prepares a complete E-mail message.
151
152   SqWebMail depends on the mail server to read the headers for recipients
153   and to strip out the Bcc: header. SqWebMail uses the black-box
154   authentication module to set the contents of the From: header and provide
155   the envelope return address.
156
157   The IP address of the HTTP client is not inserted into the headers,
158   however the wrapper and the mail server are invoked under the userid of an
159   authenticated user. The wrapper shell script can be modified to insert the
160   IP address, if so desired. The wrapper shell script has access to the CGI
161   REMOTE_ADDR environment variable.
162
163SqWebMail daemon
164
165   sqwebmaild is the meat of the code. It's a daemon process that runs as
166   root, and listens on a publicly-available UNIX domain socket. The tiny
167   sqwebmail CGI binary is a stub that connects to the daemon, forwards the
168   HTTP request, and passes along sqwebmaild output to the HTTP client.
169
170   sqwebmaild essentially receives a bunch of environment variables that
171   comprise the HTTP request. Anyone on the system may connect to
172   sqwebmaild's socket, and send it a bunch of environment variables, just
173   like anyone can connect to the server and send any HTTP request to it.
174   However, sqwebmaild places an upper limit on the size of the environment,
175   and will only accept the environment variables which are used in HTTP
176   request, discarding any environment variables that it does not recognize
177   (PATH, LD_LIBRARY_PATH, etc...).
178
179   When virtual mailboxes are being used, it is possible to run sqwebmaild
180   under the virtual userid, instead of root. Apart from the obvious changes,
181   the --with-cacheowner option must be used so that the login cache is owned
182   by the virtual userid also.
183
184   On some platforms this may not work without some additional tweaking. If
185   authenticating with sqwebmail setuided to the virtual userid doesn't work:
186
187     * Verify that the password has been correctly set.
188     * Remove the source file authlib/changeuidgid.c. Replace everything in
189       that file with the following three lines of code, exactly as shown:
190
191 void authchangegroup() {}
192 void authchangeuidgid() {}
193 void authchangeusername() {}
194
195
196     * Recompile and reinstall.
197
198   sqwebmaild takes the following action when it receives an HTTP request via
199   the local socket:
200
201     * Determine if the HTTP request is a request from a client that's
202       already logged in. The other possibilities are the login request
203       itself, or a couple of requests which are used to show the initial
204       login screen. This is determined by the presence of the extra path in
205       the HTTP request. This approach avoids the need to parse HTTP
206       arguments. If the extra path containing the login ID is present, the
207       login ID is extracted, SqWebMail changes to the account's Maildir
208       directory, and drops root privileges. The CGI environment is read, and
209       the request is authenticated (see [13]Authentication, above).
210
211     * If it's a login screen, the appropriate forms are generated.
212
213     * If it's a login request, SqWebMail makes sure that the request format
214       is NOT a multipart/formdata POST, which takes the most amount of code
215       to interpret. Additionally, requests indicating more than 128 bytes of
216       posted data are rejected prior to even parsing them. Barring all that,
217       the userid/password is fetched from the request, and processed. The
218       multipart/formdata check shouldn't be necessary given a 64 byte upper
219       limit on unauthenticated requests, but it can't hurt.
220
221References
222
223   Visible links
224   1. file:///home/mrsam/src/courier.git/sqwebmail/libs/sqwebmail/SECURITY.html#uidpass
225   2. file:///home/mrsam/src/courier.git/sqwebmail/libs/sqwebmail/SECURITY.html#mid
226   3. file:///home/mrsam/src/courier.git/sqwebmail/libs/sqwebmail/SECURITY.html#auth
227   4. file:///home/mrsam/src/courier.git/sqwebmail/libs/sqwebmail/SECURITY.html#history
228   5. file:///home/mrsam/src/courier.git/sqwebmail/libs/sqwebmail/SECURITY.html#caching
229   6. file:///home/mrsam/src/courier.git/sqwebmail/libs/sqwebmail/SECURITY.html#html
230   7. file:///home/mrsam/src/courier.git/sqwebmail/libs/sqwebmail/SECURITY.html#referral
231   8. file:///home/mrsam/src/courier.git/sqwebmail/libs/sqwebmail/SECURITY.html#sending
232   9. file:///home/mrsam/src/courier.git/sqwebmail/libs/sqwebmail/SECURITY.html#setuid
233  10. file:///home/mrsam/src/courier.git/sqwebmail/libs/sqwebmail/SECURITY.html#auth
234  11. file:///home/mrsam/src/courier.git/sqwebmail/libs/sqwebmail/SECURITY.html#html
235  12. file:///home/mrsam/src/courier.git/sqwebmail/libs/sqwebmail/SECURITY.html#referral
236  13. file:///home/mrsam/src/courier.git/sqwebmail/libs/sqwebmail/SECURITY.html#auth
237