Currently, accessing a site that uses the force-www RewriteRule defined in the default .htaccess without supplying a Host: header causes you to be redirected to "http://www./", as below:
GET / HTTP/1.0 HTTP/1.1 301 Moved Permanently Date: Tue, 24 Jul 2012 13:10:29 GMT Server: Apache/2.2.3 (CentOS) Location: http://www./ Cache-Control: max-age=1209600 Expires: Tue, 07 Aug 2012 13:10:29 GMT Vary: Accept-Encoding Content-Length: 302 Connection: close Content-Type: text/html; charset=iso-8859-1
As an additional issue, if you are accessing the site via HTTPS, you'll be downgraded to HTTP in the redirect.
I've attached three patches to address one or both of these issues, as follows:
v1: Disable redirect to "www." if no Host: header is present.
v2: If no Host: header is present, redirect to the ServerName defined in Apache for this VHost.
v3: v1, plus code to handle the http/https confusion.
Of these, v3 seems best. v2 is only included for completeness, but I'm willing to be convinced that it's the right approach.
This is a security issue because the code, as shipped (albeit commented out), is vulnerable to a MitM attack, because it redirects from secure to insecure. The security issue is demonstrated in this scenario:
Upstream MitM Linux router transparently forwards destination port 443, NATs dst_port 80 to localhost. Local port 80 is a proxy server that swaps any "https://" in the received reply from the server to be "http://", and eats the initial redirect onto "https://". Now, the client is permanently downgraded to HTTP, while the proxy server connects to the real server over HTTPS, thus keeping it happy (and oblivious to the fact that this MitM is happening).
Scenario where all content is intended to be encrypted (securepages in use, all pages are forced to HTTPS), and www. redirect is in effect:
Client manually types in: "https://drupal.org/user".
(Real) Server responds: HTTP-301, Location: http://www.drupal.org/user
Client issues request for http://www.drupal.org/user
Proxy issues request for http://www.drupal.org/user
Server responds: HTTP-301, Location: https://www.drupal.org/user
Proxy issues request for https://www.drupal.org/user
Server delivers content to proxy
Proxy delivers content to client, with s#https://#http://#g
Lather, rinse, repeat.
The client doesn't trust his network, and therefore properly typed in (or used a bookmark for) https://, and the SSL negotiation worked, since they really were hitting the intended destination site. But as soon as the connection is downgraded to HTTP, our attacker swoops in and makes sure it never gets pushed back onto HTTPS, even as, from the perspective of the server, it has been.
(see also https://security.drupal.org/node/76983)