diff options
Diffstat (limited to 'sqwebmail/SECURITY.html')
| -rw-r--r-- | sqwebmail/SECURITY.html | 238 | 
1 files changed, 238 insertions, 0 deletions
| diff --git a/sqwebmail/SECURITY.html b/sqwebmail/SECURITY.html new file mode 100644 index 0000000..7577e0e --- /dev/null +++ b/sqwebmail/SECURITY.html @@ -0,0 +1,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><SCRIPT>, +    </SCRIPT>, <APP>, </APP>, <APPLET>, +    </APPLET>, <SERVER>, </SERVER>, <OBJECT>, +    </OBJECT>, <HTML>, </HTML>, <HEAD>, +    </HEAD>, <BODY>, </BODY>, <META>, <TITLE>, +    </TITLE>, <FRAME>, </FRAME>, <LINK>, +    <IFRAME> and </IFRAME></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><A></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> | 
