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

Reply via email to