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 */