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...@locus.apache.org on 2000/10/18 06:50:25 UTC

cvs commit: apache-2.0/src/modules/standard mod_rewrite.c mod_rewrite.h

fanf        00/10/17 21:50:25

  Modified:    src      CHANGES
               src/modules/standard mod_rewrite.c mod_rewrite.h
  Log:
  Restore functionality broken by the mod_rewrite security fix:
  rewrite map lookup keys and default values are now expanded
  so that the lookup can depend on the requested URI etc.
  
  Because the new code is recursive you can now write configurations
  like the following (with nested map lookups) which wasn't directly
  possible before -- you had to use a RewriteCond and a %N backref
  instead, as in http://www.apache.org/docs/vhosts/mass.html#xtra-conf
  
  RewriteMap tolower int:tolower
  RewriteMap host2user txt:/home/www/conf/virtusertbl
  RewriteRule /(.*) /home/${host2user:${tolower:%{HTTP_HOST}}|www}/public_html
  
  PR: 6671
  
  Revision  Changes    Path
  1.281     +6 -0      apache-2.0/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/CHANGES,v
  retrieving revision 1.280
  retrieving revision 1.281
  diff -u -u -r1.280 -r1.281
  --- CHANGES	2000/10/18 04:48:34	1.280
  +++ CHANGES	2000/10/18 04:50:24	1.281
  @@ -1,5 +1,10 @@
   Changes with Apache 2.0a8
   
  +  *) Restore functionality broken by the mod_rewrite security fix:
  +     rewrite map lookup keys and default values are now expanded
  +     so that the lookup can depend on the requested URI etc.
  +     PR #6671 [Tony Finch]
  +
     *) Tighten up the syntax checking of Host: headers to fix a
        security bug in some mass virtual hosting configurations
        that can allow a remote attacker to retrieve some files
  @@ -107,6 +112,7 @@
        [Bill Stoddard]
   
   Changes with Apache 2.0a7
  +
     *) Reimplement core_output_filter to buffer/save bucket brigades
        across multiple calls to the core_filter. The brigade will be
        sent when either MIN_BYTES_TO_SEND or MAX_IOVEC_TO_WRITE
  
  
  
  1.43      +47 -5     apache-2.0/src/modules/standard/mod_rewrite.c
  
  Index: mod_rewrite.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/modules/standard/mod_rewrite.c,v
  retrieving revision 1.42
  retrieving revision 1.43
  diff -u -u -r1.42 -r1.43
  --- mod_rewrite.c	2000/10/16 06:05:06	1.42
  +++ mod_rewrite.c	2000/10/18 04:50:25	1.43
  @@ -2320,30 +2320,50 @@
   	/* now we have a '$' or a '%' */
   	if (inp[1] == '{') {
   	    char *endp;
  -	    endp = strchr(inp, '}');
  +	    endp = find_closing_bracket(inp+2, '{', '}');
   	    if (endp == NULL) {
   		goto skip;
   	    }
   	    *endp = '\0';
   	    if (inp[0] == '$') {
   		/* ${...} map lookup expansion */
  +		/*
  +		 * To make rewrite maps useful the lookup key and
  +		 * default values must be expanded, so we make
  +		 * recursive calls to do the work. For security
  +		 * reasons we must never expand a string that includes
  +		 * verbatim data from the network. The recursion here
  +		 * isn't a problem because the result of expansion is
  +		 * only passed to lookup_map() so it cannot be
  +		 * re-expanded, only re-looked-up. Another way of
  +		 * looking at it is that the recursion is entirely
  +		 * driven by the syntax of the nested curly brackets.
  +		 */
   		char *key, *dflt, *result;
  +		char xkey[MAX_STRING_LEN];
  +		char xdflt[MAX_STRING_LEN];
  +		char *empty = "";
   		key = strchr(inp, ':');
   		if (key == NULL) {
   		    goto skip;
   		}
   		*key++ = '\0';
   		dflt = strchr(key, '|');
  -		if (dflt) {
  +		if (dflt == NULL) {
  +		    dflt = empty;
  +		}
  +		else
   		    *dflt++ = '\0';
   		}
  -		result = lookup_map(r, inp+2, key);
  +		do_expand(r, key,  xkey,  sizeof(xkey),  briRR, briRC);
  +		do_expand(r, dflt, xdflt, sizeof(xdflt), briRR, briRC);
  +		result = lookup_map(r, inp+2, xkey);
   		if (result == NULL) {
  -		    result = dflt ? dflt : "";
  +		    result = xdflt;
   		}
   		span = apr_cpystrn(outp, result, space) - outp;
   		key[-1] = ':';
  -		if (dflt) {
  +		if (dflt != empty) {
   		    dflt[-1] = '|';
   		}
   	    }
  @@ -4084,6 +4104,28 @@
           }
       }
       return 0;
  +}
  +
  +/*
  +**
  +**  Find end of bracketed expression
  +**  s points after the opening bracket
  +**
  +*/
  +
  +static char *find_closing_bracket(char *s, int left, int right)
  +{
  +    int depth;
  +
  +    for (depth = 1; *s; ++s) {
  +	if (*s == right && --depth == 0) {
  +	    return s;
  +	}
  +	else if (*s == left) {
  +	    ++depth;
  +	}
  +    }
  +    return NULL;
   }
   
   #ifdef NETWARE
  
  
  
  1.19      +3 -0      apache-2.0/src/modules/standard/mod_rewrite.h
  
  Index: mod_rewrite.h
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/modules/standard/mod_rewrite.h,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -u -r1.18 -r1.19
  --- mod_rewrite.h	2000/09/23 00:05:45	1.18
  +++ mod_rewrite.h	2000/10/18 04:50:25	1.19
  @@ -469,6 +469,9 @@
       /* Lexicographic Comparison */
   static int compare_lexicography(char *cpNum1, char *cpNum2);
   
  +    /* Find end of bracketed expression */
  +static char *find_closing_bracket(char *s, int left, int right);
  +
   #endif /* _MOD_REWRITE_H */
   
   /*EOF*/