httpd-bugs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
Subject DO NOT REPLY [Bug 35892] New: - Schitzoid handling of name-based virtual server ports when UseCanonicalName False
Date Wed, 27 Jul 2005 10:35:26 GMT

           Summary: Schitzoid handling of name-based virtual server ports
                    when UseCanonicalName False
           Product: Apache httpd-2.0
           Version: 2.0.54
          Platform: All
        OS/Version: NetBSD
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Core

This applies to name-based virtual servers.

When UseCanonicalName is true, get_server_name and get_server_port (and, by
extension, construct_url and all generated redirects) use the hostname and port
specified in the configuration file.

However, when UseCanonicalName is false, these use the hostname and port
supplied by the user. In the case of the hostname, this is fine; the server has
no way actually to find out what hostname the client really used; it can only
trust what the client passed in in the host header.  However, the port is a
different case; because the destination port number was specified in the TCP
request itself, the server knows both what the client told it (in the Host
header) and what the client really used (from the TCP connection), assuming that
there are no proxies between that are rewriting the port number.

Note that clients sometimes do use a port different from what they say they
used; this is a known bug in many versions of Internet explorer. If IE is given
a redirect to the same host but a different port, when following the redirect it
will re-use the old Host header (with the old port number) rather than generate
a new Host head with the port number that it's actually using for the request.

Now apache, when it gets a request and is looking up a name-based virtual host,
trusts the client for the name, but does not trust the client for the port
number. So if there are two virtual hosts, foo:123 and foo:456, and it receives
a request on port 456 with a host header asking for foo:123, apache will instead
use virtual host foo:456 to satisfy the request. It is clamed that this is for
security reasons, though these reasons are not clear.

Unfortunately, this means that when apache (or anybody else using construct_url)
generates a redirect under these circumstances, it will generate a redirect not
to the virtual host Apache used to satisfy the request, but to the host that the
client claimed to be looking for (which Apache did not use).

It appears that one of the reasons for this behavior is the resolution of bug
25515: there are circumstances (where a proxy in between is changing port
numbers) where apache also does not know the port number the client actually
used. E.g., the client connects to external:82, which is a NAT device that
fowardards this to internal:80.

However, it seems to me that this fix was not so well thought through, since
that brought about this bizarre situation where apache believes clients about
the hostname regardless, but doesn't believe them about the port when serving
the request, yet believes them about the port when issuing redirects. I would
say that, in the absence of an apache that will believe the client about the
port as well as host, the better solution to bug 25515 is to fix the
configuration of the internal apache and make it listen on port 82 (as well as
80, if necessary), since you're otherwise effectively using the NAT device to
lie to apache, and expecting apache to understand that this is a lie.

So what is the correct solution here? I would say the best option is, when you
accept a request with a Host: header, search for the virtual server based on
that, both name and port. As far as I can see, any security considerations that
would apply here (e.g., that port is supposed to be blocked on the firewall)
also apply to the name (the host with that name is supposed to be blocked on the
firewall). Arbitrarially believing the name is no worse than arbitrarially
believing the port; in both cases you have to realize that the data comes from
the client and configure apache appropriately for your security needs, rather
than depending on a firewall.

Failing that, you could add an option to UseCanonicalName to, instead of using
both name and port or neither, follow apache's practice when searching for the
virtual host to serve a request of using the name supplied by the client but the
port suppplied by the operating system.

The workaround, for this at the moment, is to write your own construct_url
function that uses the server name from the request (get_server_name) but the
port number from the server used to serve the request (instead of the request's
get_server_port). However, while that works for redirects generated by code
using Apache, Apache itself will still issue incorrect redirects.

Configure bugmail:
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message