httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ruediger Pluem <rpl...@apache.org>
Subject Re: svn commit: r573831 - in /httpd/httpd/trunk: CHANGES docs/manual/mod/mod_rewrite.xml modules/mappers/mod_rewrite.c
Date Sun, 09 Sep 2007 09:41:53 GMT


On 09/08/2007 02:46 PM, wrote:
> Author: niq
> Date: Sat Sep  8 05:46:10 2007
> New Revision: 573831
> 
> URL: http://svn.apache.org/viewvc?rev=573831&view=rev
> Log:
> Add option to escape backreferences in RewriteRule.
> PR 34602  and  PR 39746
> Patch by Guenther Gsenger
> 
> Modified:
>     httpd/httpd/trunk/CHANGES
>     httpd/httpd/trunk/docs/manual/mod/mod_rewrite.xml
>     httpd/httpd/trunk/modules/mappers/mod_rewrite.c
> 

> 
> Modified: httpd/httpd/trunk/docs/manual/mod/mod_rewrite.xml
> URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/mod_rewrite.xml?rev=573831&r1=573830&r2=573831&view=diff
> ==============================================================================
> --- httpd/httpd/trunk/docs/manual/mod/mod_rewrite.xml (original)
> +++ httpd/httpd/trunk/docs/manual/mod/mod_rewrite.xml Sat Sep  8 05:46:10 2007
> @@ -1243,6 +1243,21 @@
>        brackets, of any of the following flags: </p>
>  
>        <dl>
> +        <dt>'<code>B</code>' (escape backreferences)</dt>
> +        <dd><p>Apache has to unescape URLs before mapping them,
> +        so backreferences will be unescaped at the time they are applied.
> +        Using the B flag, non-alphanumeric characters in backreferences
> +        will be escaped.  For example, consider the rule:</p>
> +        <pre><code> RewriteRule RewriteRule ^(.*)$   index.php?show=$1 </code></pre>
> +        <p>This will map <code>/C++</code> to <code>index.php?show=C++</code>.
> +        But it will also map <code>/C%2b%2b</code> to
> +        <code>index.php?show=C++</code>, because the <code>%2b</code>
> +        has been unescaped.  With the B flag, it will instead map to
> +        <code>index.php?show=>/C%2b%2b</code>.</p>
> +        <p>This escaping is particularly necessary in a proxy situation,
> +        when the backend may break if presented with an unescaped URL.</p>
> +        </dd>
> +

I am a little bit unsure if this can have security implications in some cases.

>
> 
> Modified: httpd/httpd/trunk/modules/mappers/mod_rewrite.c
> URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/mappers/mod_rewrite.c?rev=573831&r1=573830&r2=573831&view=diff
> ==============================================================================
> --- httpd/httpd/trunk/modules/mappers/mod_rewrite.c (original)
> +++ httpd/httpd/trunk/modules/mappers/mod_rewrite.c Sat Sep  8 05:46:10 2007

> @@ -635,6 +637,46 @@
>      return 0;
>  }
>  
> +static const char c2x_table[] = "0123456789abcdef";
> +
> +static APR_INLINE unsigned char *c2x(unsigned what, unsigned char prefix,
> +                                     unsigned char *where)
> +{
> +#if APR_CHARSET_EBCDIC
> +    what = apr_xlate_conv_byte(ap_hdrs_to_ascii, (unsigned char)what);
> +#endif /*APR_CHARSET_EBCDIC*/
> +    *where++ = prefix;
> +    *where++ = c2x_table[what >> 4];
> +    *where++ = c2x_table[what & 0xf];
> +    return where;
> +}
> +
> +/*
> + * Escapes a uri in a similar way as php's urlencode does.
> + * Based on ap_os_escape_path in server/util.c
> + */
> +static char *escape_uri(apr_pool_t *p, const char *path) {
> +    char *copy = apr_palloc(p, 3 * strlen(path) + 3);
> +    const unsigned char *s = (const unsigned char *)path;
> +    unsigned char *d = (unsigned char *)copy;
> +    unsigned c;
> +
> +    while ((c = *s)) {
> +        if (apr_isalnum(c) || c == '_') {
> +            *d++ = c;
> +        }
> +        else if (c == ' ') {
> +            *d++ = '+';
> +        }
> +        else {
> +            d = c2x(c, '%', d);
> +        }
> +        ++s;
> +    }
> +    *d = '\0';
> +    return copy;
> +}
> +

Does it make sense to duplicate code? Shouldn't this be placed in util.c?

>  /*
>   * escape absolute uri, which may or may not be path oriented.
>   * So let's handle them differently.

> @@ -2322,9 +2364,23 @@
>              if (bri->source && n < AP_MAX_REG_MATCH
>                  && bri->regmatch[n].rm_eo > bri->regmatch[n].rm_so)
{
>                  span = bri->regmatch[n].rm_eo - bri->regmatch[n].rm_so;
> -
> -                current->len = span;
> -                current->string = bri->source + bri->regmatch[n].rm_so;
> +                if (entry && (entry->flags & RULEFLAG_ESCAPEBACKREF))
{
> +                    /* escape the backreference */
> +                    char *tmp2, *tmp;
> +                    tmp = apr_palloc(pool, span + 1);
> +                    strncpy(tmp, bri->source + bri->regmatch[n].rm_so, span);

How about using apr_pstrndup instead?

> +                    tmp[span] = '\0';
> +                    tmp2 = escape_uri(pool, tmp);
> +                    rewritelog((ctx->r, 5, ctx->perdir, "escaping backreference
'%s' to '%s'",
> +                            tmp, tmp2));
> +
> +                    current->len = span = strlen(tmp2);
> +                    current->string = tmp2;
> +                } else {
> +                    current->len = span;
> +                    current->string = bri->source + bri->regmatch[n].rm_so;
> +                }
> +                
>                  outlen += span;
>              }
>  

Regards

RĂ¼diger

Mime
View raw message