fanf 99/12/20 09:43:41
Modified: src CHANGES
src/main http_protocol.c http_vhost.c
src/modules/standard mod_vhost_alias.c
Log:
A better fix for the mass virtual hosting security problem spotted by Lars.
This solves the problem for mod_rewrite setups as well as mod_vhost_alias.
Submitted by: Ben Hyde
Reviewed by: Tony Finch
Revision Changes Path
1.1484 +5 -0 apache-1.3/src/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/apache-1.3/src/CHANGES,v
retrieving revision 1.1483
retrieving revision 1.1484
diff -u -r1.1483 -r1.1484
--- CHANGES 1999/12/17 22:25:11 1.1483
+++ CHANGES 1999/12/20 17:43:25 1.1484
@@ -1,5 +1,10 @@
Changes with Apache 1.3.10
+ *) More rigorous checking of Host: headers to fix security problems
+ with mass name-based virtual hosting (whether using mod_rewrite
+ or mod_vhost_alias).
+ [Ben Hyde, Tony Finch]
+
*) Updated README.config to reflect current APACI state.
[Brian Slesinsky <[EMAIL PROTECTED]>] PR#5397
1.284 +3 -1 apache-1.3/src/main/http_protocol.c
Index: http_protocol.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/http_protocol.c,v
retrieving revision 1.283
retrieving revision 1.284
diff -u -r1.283 -r1.284
--- http_protocol.c 1999/12/09 12:05:03 1.283
+++ http_protocol.c 1999/12/20 17:43:35 1.284
@@ -1045,7 +1045,7 @@
r->status = HTTP_OK; /* Until further notice. */
/* update what we think the virtual host is based on the headers we've
- * now read
+ * now read. may update status.
*/
ap_update_vhost_from_headers(r);
@@ -1068,6 +1068,8 @@
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
"client sent HTTP/1.1 request without hostname "
"(see RFC2068 section 9, and 14.23): %s", r->uri);
+ }
+ if (r->status != HTTP_OK) {
ap_send_error_response(r, 0);
ap_log_transaction(r);
return r;
1.16 +41 -10 apache-1.3/src/main/http_vhost.c
Index: http_vhost.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/http_vhost.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- http_vhost.c 1999/01/01 19:04:51 1.15
+++ http_vhost.c 1999/12/20 17:43:37 1.16
@@ -657,22 +657,51 @@
* run-time vhost matching functions
*/
-/* Remove :port and optionally a single trailing . from the hostname, this
- * canonicalizes it somewhat.
+/* Lowercase and remove any trailing dot and/or :port from the hostname,
+ * and check that it is sane.
*/
static void fix_hostname(request_rec *r)
{
- const char *hostname = r->hostname;
- char *host = ap_getword(r->pool, &hostname, ':'); /* get rid of
port */
- size_t l;
-
- /* trim a trailing . */
- l = strlen(host);
- if (l > 0 && host[l-1] == '.') {
- host[l-1] = '\0';
+ char *host = ap_palloc(r->pool, strlen(r->hostname) + 1);
+ const char *src;
+ char *dst;
+
+ /* check and copy the host part */
+ src = r->hostname;
+ dst = host;
+ while (*src) {
+ if (!isalnum(*src) && *src != '.' && *src != '-') {
+ if (*src == ':')
+ break;
+ else
+ goto bad;
+ } else {
+ *dst++ = tolower(*src++);
+ }
+ }
+ /* check the port part */
+ if (*src++ == ':') {
+ while (*src) {
+ if (!isdigit(*src++)) {
+ goto bad;
+ }
+ }
+ }
+ /* strip trailing gubbins */
+ if (dst > host && dst[-1] == '.') {
+ dst[-1] = '\0';
+ } else {
+ dst[0] = '\0';
}
r->hostname = host;
+ return;
+
+bad:
+ r->status = HTTP_BAD_REQUEST;
+ ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
+ "Client sent malformed Host header");
+ return;
}
@@ -874,6 +903,8 @@
/* must set this for HTTP/1.1 support */
if (r->hostname || (r->hostname = ap_table_get(r->headers_in, "Host"))) {
fix_hostname(r);
+ if (r->status != HTTP_OK)
+ return;
}
/* check if we tucked away a name_chain */
if (r->connection->vhost_lookup_data) {
1.4 +6 -12 apache-1.3/src/modules/standard/mod_vhost_alias.c
Index: mod_vhost_alias.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/modules/standard/mod_vhost_alias.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- mod_vhost_alias.c 1999/12/20 05:24:22 1.3
+++ mod_vhost_alias.c 1999/12/20 17:43:40 1.4
@@ -278,8 +278,8 @@
}
}
-static int vhost_alias_interpolate(request_rec *r, const char *name,
- const char *map, const char *uri)
+static void vhost_alias_interpolate(request_rec *r, const char *name,
+ const char *map, const char *uri)
{
/* 0..9 9..0 */
enum { MAXDOTS = 19 };
@@ -390,11 +390,8 @@
}
}
vhost_alias_checkspace(r, buf, &dest, end - start);
- for (p = start; p < end; ++p) {
- if (!isalnum(*p) && *p != '-' && *p != '.')
- return HTTP_BAD_REQUEST;
- *dest++ = ap_tolower(*p);
- }
+ memcpy(dest, start, end-start);
+ dest += end-start;
}
*dest = '\0';
/* no double slashes */
@@ -407,7 +404,6 @@
else {
r->filename = ap_pstrcat(r->pool, buf, uri, NULL);
}
- return OK;
}
static int mva_translate(request_rec *r)
@@ -415,7 +411,7 @@
mva_sconf_t *conf;
const char *name, *map, *uri;
mva_mode_e mode;
- int cgi, bad;
+ int cgi;
conf = (mva_sconf_t *) ap_get_module_config(r->server->module_config,
&vhost_alias_module);
@@ -449,9 +445,7 @@
return DECLINED;
}
- bad = vhost_alias_interpolate(r, name, map, uri);
- if (bad != OK)
- return bad;
+ vhost_alias_interpolate(r, name, map, uri);
if (cgi) {
/* see is_scriptaliased() in mod_cgi */