You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by fa...@hyperreal.org on 1999/12/21 12:33:24 UTC

cvs commit: apache-2.0/src/main http_protocol.c http_vhost.c

fanf        99/12/21 03:33:23

  Modified:    src      CHANGES
               src/main http_protocol.c http_vhost.c
  Log:
  Fix the mass vhosting security problem spotted by Lars, as in 1.3
  Submitted by:	Ben Hyde
  Reviewed by:	Tony Finch
  
  Revision  Changes    Path
  1.19      +5 -0      apache-2.0/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/CHANGES,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- CHANGES	1999/12/21 07:54:07	1.18
  +++ CHANGES	1999/12/21 11:33:21	1.19
  @@ -1,4 +1,9 @@
   Changes with Apache 2.0-dev
  +
  +  *) 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]
     
     *) Add back support for UseCanonicalName in <Directory> containers.
        [Manoj Kasichainula]
  
  
  
  1.43      +3 -1      apache-2.0/src/main/http_protocol.c
  
  Index: http_protocol.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/main/http_protocol.c,v
  retrieving revision 1.42
  retrieving revision 1.43
  diff -u -r1.42 -r1.43
  --- http_protocol.c	1999/12/20 16:38:34	1.42
  +++ http_protocol.c	1999/12/21 11:33:22	1.43
  @@ -1033,7 +1033,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);
   
  @@ -1056,6 +1056,8 @@
           ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, 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_run_log_transaction(r);
           return r;
  
  
  
  1.10      +41 -10    apache-2.0/src/main/http_vhost.c
  
  Index: http_vhost.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/main/http_vhost.c,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- http_vhost.c	1999/12/15 00:59:56	1.9
  +++ http_vhost.c	1999/12/21 11:33:23	1.10
  @@ -658,22 +658,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++ = *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;
   }
   
   
  @@ -876,6 +905,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) {