This file is indexed.

/usr/share/doc/sqwebmail/SECURITY.html is in sqwebmail 0.68.2-1ubuntu3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
  <meta name="MSSmartTagsPreventParsing" content="TRUE" />
  <meta name="Author" content="Sam Varshavchik" />
  <title>SqWebMail security</title>
  <!-- Copyright 1998 - 2003 Double Precision, Inc.  See COPYING for -->
  <!-- distribution information. -->
</head>

<body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B"
alink="#FF0000">
<h1>SqWebMail security</h1>
This document discloses security-oriented issues regarding the SqWebMail CGI
application.

<p>In this document:</p>
<ul>
  <li><a href="#uidpass">User IDs and Passwords</a></li>
  <li><a href="#mid">Mailbox IDs</a></li>
  <li><a href="#auth">Authentication</a></li>
  <li><a href="#history">Browser Security - History</a></li>
  <li><a href="#caching">Browser Security - Caching</a></li>
  <li><a href="#html">Browser Security - HTML</a></li>
  <li><a href="#referral">Browser Security - Referer: Tags</a></li>
  <li><a href="#sending">Sending Mail</a></li>
  <li><a href="#setuid">Setuid Root</a></li>
</ul>

<h2><a name="uidpass" id="uidpass"></a>User IDs and Passwords</h2>
SqWebMail's security scheme requires a valid userid/password to access an
account. The actual method for validating the userid and password is a
black-box module that can be easily replaced. The example black-box
implementation uses the PAM library, if available, or with the /etc/passwd,
/etc/shadow and the crypt() function.

<p>It is possible to configure SqWebMail to transmit the userid and password
via secure HTTP. If secure HTTP is not available, the userid and password is
transmitted over the network in the clear, which can be picked up by a
sniffer.</p>

<h2><a name="mid" id="mid"></a>Mailbox IDs</h2>
After a userid and password is authenticated, the authentication module
returns a 'mailboxid'. The mailboxid is used as a handle for the mailbox. A
mailboxid may not necessarily be the same as the userid, but the sample
authentication modules make them the same.

<p>Technically, the mailboxid that's generated by recent versions of
sqwebmail are of the form "<tt>userid.method</tt>", where method represents
the authentication module that was used.</p>

<p>A mailboxid is sent with every HTTP request, in the request itself. Note
that the mailboxid is transmitted over the network in the clear. It is also
possible to use secure HTTP for the every HTTP request, not just initial
authentication, but this has not been tested.</p>

<p>Unless the mailboxid is the same as a userid, there aren't many security
considerations in having the mailboxid broadcasted over the network. That's
because the mailboxid in the HTTP request is usually validated based on a
time-limited IP address (see "<a href="#auth">Authentication</a>"). Note that
there certain other potential ways - in addition to network traffic sniffing
- for an unauthorized party to attempt to grab mailboxids. See "<a
href="#html">Browser Security - HTML</a>", and "<a href="#referral">Browser
Security - Referrer: Tags</a>".</p>

<h2><a name="auth" id="auth"></a>Authentication</h2>
Once the user ID and password are authenticated, authentication for
subsequent HTTP requests is based on a combination of an IP address, plus a
128-bit random number that was generated during the login.

<p>By default, SqWebMail permits access to the mailbox only from the same IP
address as the one where the user ID and password was authenticated from.
This can be selectively turned off at login time, in cases where the client
is behind a load-balancing firewall that uses multiple IP addresses. In all
cases, a 128-bit random number must be transmitted with every HTTP request,
and it must match the number generated during the login, which is saved in
the Maildir directory.</p>

<p>The Maildir directory must therefore have any group or world access rights
disabled. Additionally, every page served by SqWebMail includes HTTP headers
containing instructions to proxies and browsers that prohibit this page from
being cached. There are some buggy web browsers out there - most of them
originating in Redmond,WA - that ignore these caching directives, and they
end up saving the 128-bit random number in the local cache. Unless access to
the physical machine is secured, the local cache can be trawled to obtain the
128-bit authentication token.</p>

<p>However, access to the mailbox is allowed only for a maximum period of
time after the initial authentication. Access is allowed only if the HTTP
requests come within a different, shorter period of time. If no access
requests have been made for a certain period of time, access will no longer
be available even if it comes from the right IP address, with the right
authentication token.</p>

<p>The IP address of the initial authentication, the dates and times
involved, are all stored in files in the maildir directory, with group and
world permissions turned off.</p>

<h2><a name="history" id="history"></a>Browser Security - History</h2>
In certain situations a mailboxid is a part of the actual URL requested. A
browser may maintain a history file of visited URLs.

<p>SqWebMail uses a frame window in an attempt to keep the browser from
recording visited URLs. This approach works for most popular web browsers
that support frames - these browsers do not maintain history for individual
frames. Note that frames are not required to access the full SqWebMail
functionality.</p>

<h2><a name="caching" id="caching"></a>Browser Security - Caching</h2>
SqWebMail sets the expiration header on every HTTP page it serves. Individual
pages contain URLs and hidden fields with mailboxids. The expiration header
should keep the web pages from being saved in the browser cache.

<h2><a name="html" id="html"></a>Browser Security - HTML</h2>
SqWebMail has the ability to display HTML E-mail, which leads to several
complicated situations regarding embedded Javascript or Java applets that try
to grab the mailboxid of the recipient (amongst other things). SqWebMail
attempts to remove all forms of scripting from HTML E-mail as follows:
<ul>
  <li>The following HTML tags are removed: <tt>&lt;SCRIPT&gt;,
    &lt;/SCRIPT&gt;, &lt;APP&gt;, &lt;/APP&gt;, &lt;APPLET&gt;,
    &lt;/APPLET&gt;, &lt;SERVER&gt;, &lt;/SERVER&gt;, &lt;OBJECT&gt;,
    &lt;/OBJECT&gt;, &lt;HTML&gt;, &lt;/HTML&gt;, &lt;HEAD&gt;,
    &lt;/HEAD&gt;, &lt;BODY&gt;, &lt;/BODY&gt;, &lt;META&gt;, &lt;TITLE&gt;,
    &lt;/TITLE&gt;, &lt;FRAME&gt;, &lt;/FRAME&gt;, &lt;LINK&gt;,
    &lt;IFRAME&gt; and &lt;/IFRAME&gt;</tt>.</li>
  <li>The following HTML attributes are stripped from every tag:
    <tt>ONLOAD=</tt>, <tt>ONMOUSEOVER=</tt>, and all <tt>ON*=</tt>
    attributes; <tt>BACKGROUND=</tt>, <tt>STYLE=</tt>, <tt>TARGET=</tt>,
    <tt>CODE=</tt>, <tt>CODETYPE=</tt>, and <tt>LANGUAGE=</tt> are removed;
    <tt>TARGET=_blank</tt> is added to all <tt>&lt;A&gt;</tt> tags.</li>
  <li>The HREF and SRC attributes are stripped, unless the URL starts with
    one of the following: <tt>http:, https:, ftp:, gopher:, wais:,</tt> or
    <tt>telnet</tt>, and <tt>cid:</tt>.</li>
  <li>The HREF and SRC attribute values are prefixed with a URL that will
    resolve to SqWebMail, and with an additional <tt>TARGET="_blank"</tt>
    attribute. A request to that resulting URL will result in a blank page
    with a 0-second refresh to the original URL. This method strips mailbox
    IDs from Referer: tags sent to external web site. If the HREF attribute
    starts with a <tt>cid:</tt>, it is replaced by an http: reference to
    SqWebMail that will return the specified MIME part.</li>
  <li><tt>IMG</tt> tags are removed and replaced with an <tt>A</tt> tag, in
    order to keep the HTTP client from automatically loading any images from
    external web sites, upon opening a given message.</li>
  <li>Everything inside the <tt>STYLE</tt> tag is removed.</li>
</ul>

<h2><a name="referral" id="referral"></a>Browser Security - Referer: Tags</h2>
See the previous section regarding how SqWebMail attempts to remove mailbox
IDs from <tt>Referer:</tt> tags.

<h2><a name="sending" id="sending"></a>Sending Mail</h2>
SqWebMail includes the ability to send mail. Issues regarding transmitting
E-mail from the HTTP client to the server are obvious. SqWebMail runs a
wrapper shell script in order to send the E-mail message. The wrapper shell
script normally runs qmail-inject, sendmail, or something else, immediately.
SqWebMail prepares a complete E-mail message.

<p>SqWebMail depends on the mail server to read the headers for recipients
and to strip out the Bcc: header. SqWebMail uses the black-box authentication
module to set the contents of the From: header and provide the envelope
return address.</p>

<p>The IP address of the HTTP client is not inserted into the headers,
however the wrapper and the mail server are invoked under the userid of an
authenticated user. The wrapper shell script can be modified to insert the IP
address, if so desired. The wrapper shell script has access to the CGI
<tt>REMOTE_ADDR</tt> environment variable. <br />
</p>

<h2><a name="setuid" id="setuid">SqWebMail daemon</a></h2>

<p><code>sqwebmaild</code> is the meat of the code. It's a daemon process
that runs as root, and listens on a publicly-available UNIX domain socket.
The tiny <code>sqwebmail</code> CGI binary is a stub that connects to the
daemon, forwards the HTTP request, and passes along <code>sqwebmaild</code>
output to the HTTP client.</p>

<p><code>sqwebmaild</code> essentially receives a bunch of environment
variables that comprise the HTTP request. Anyone on the system may connect to
<code>sqwebmaild</code>'s socket, and send it a bunch of environment
variables, just like anyone can connect to the server and send any HTTP
request to it. However, <code>sqwebmaild</code> places an upper limit on the
size of the environment, and will only accept the environment variables which
are used in HTTP request, discarding any environment variables that it does
not recognize (PATH, LD_LIBRARY_PATH, etc...).</p>

<p>When virtual mailboxes are being used, it is possible to run
<code>sqwebmaild</code> under the virtual userid, instead of root. Apart from
the obvious changes, the <code>--with-cacheowner</code> option must be used
so that the login cache is owned by the virtual userid also.</p>

<p>On some platforms this may not work without some additional tweaking. If
authenticating with sqwebmail setuided to the virtual userid doesn't work:</p>
<ul>
  <li>Verify that the password has been correctly set.</li>
  <li>Remove the source file authlib/changeuidgid.c. Replace everything in
    that file with the following three lines of code, exactly as shown:
    <pre>void authchangegroup() {}
void authchangeuidgid() {}
void authchangeusername() {}
    </pre>
  </li>
  <li>Recompile and reinstall.</li>
</ul>

<p><code>sqwebmaild</code> takes the following action when it receives an
HTTP request via the local socket:</p>
<ul>
  <li>Determine if the HTTP request is a request from a client that's already
    logged in. The other possibilities are the login request itself, or a
    couple of requests which are used to show the initial login screen. This
    is determined by the presence of the extra path in the HTTP request. This
    approach avoids the need to parse HTTP arguments. If the extra path
    containing the login ID is present, the login ID is extracted, SqWebMail
    changes to the account's Maildir directory, and drops root privileges.
    The CGI environment is read, and the request is authenticated (see <a
    href="#auth">Authentication</a>, above).<br />
    <br />
  </li>
  <li>If it's a login screen, the appropriate forms are generated.<br />
    <br />
  </li>
  <li>If it's a login request, SqWebMail makes sure that the request format
    is NOT a <tt>multipart/formdata</tt> POST, which takes the most amount of
    code to interpret. Additionally, requests indicating more than 128 bytes
    of posted data are rejected prior to even parsing them. Barring all that,
    the userid/password is fetched from the request, and processed. The
    <tt>multipart/formdata</tt> check shouldn't be necessary given a 64 byte
    upper limit on unauthenticated requests, but it can't hurt.</li>
</ul>

<p></p>
</body>
</html>