From: Jim Jagielski Date: Tue, 10 Jul 2012 14:10:40 +0000 (+0000) Subject: * mod_rewrite: add "AllowAnyURI" option. X-Git-Tag: 2.4.3~330 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=64b94b8a987536adcf219b8694d674a3a26b2b21;p=apache * mod_rewrite: add "AllowAnyURI" option. trunk patch: http://svn.apache.org/viewvc?rev=1356115&view=rev http://svn.apache.org/viewvc?view=revision&revision=1356813 2.4.x patch: http://people.apache.org/~jorton/httpd-pr52774.patch +1: jorton, covener, druggeri, jim git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1359687 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 94df531e82..c39538d992 100644 --- a/CHANGES +++ b/CHANGES @@ -8,6 +8,8 @@ Changes with Apache 2.4.3 possible XSS for a site where untrusted users can upload files to a location with MultiViews enabled. [Niels Heinen ] + *) mod_rewrite: Add "AllowAnyURI" option. PR 52774. [Joe Orton] + *) htdbm, htpasswd: Don't crash if crypt() fails (e.g. with FIPS enabled). [Paul Wouters , Joe Orton] diff --git a/STATUS b/STATUS index 1071a75e73..0dfe3e6fa2 100644 --- a/STATUS +++ b/STATUS @@ -109,12 +109,6 @@ PATCHES ACCEPTED TO BACKPORT FROM TRUNK: 2.4.x patch: trunk patch works +1: jorton, covener, jim - * mod_rewrite: add "AllowAnyURI" option. - trunk patch: http://svn.apache.org/viewvc?rev=1356115&view=rev - http://svn.apache.org/viewvc?view=revision&revision=1356813 - 2.4.x patch: http://people.apache.org/~jorton/httpd-pr52774.patch - +1: jorton, covener, druggeri, jim - PATCHES PROPOSED TO BACKPORT FROM TRUNK: [ New proposals should be added at the end of the list ] diff --git a/docs/manual/mod/mod_rewrite.xml b/docs/manual/mod/mod_rewrite.xml index 7ba1eddd3f..ae2b9acc6a 100644 --- a/docs/manual/mod/mod_rewrite.xml +++ b/docs/manual/mod/mod_rewrite.xml @@ -188,6 +188,38 @@ later later.

+
AllowAnyURI
+
+ +

When RewriteRule + is used in VirtualHost or server context with + version 2.2.22 or later of httpd, mod_rewrite + will only process the rewrite rules if the request URI is a URL-path. This avoids + some security issues where particular rules could allow + "surprising" pattern expansions (see CVE-2011-3368 + and CVE-2011-4317). + To lift the restriction on matching a URL-path, the + AllowAnyURI option can be enabled, and + mod_rewrite will apply the rule set to any + request URI string, regardless of whether that string matches + the URL-path grammar required by the HTTP specification.

+ + + Security Warning + +

Enabling this option will make the server vulnerable to + security issues if used with rewrite rules which are not + carefully authored. It is strongly recommended + that this option is not used. In particular, beware of input + strings containing the '@' character which could + change the interpretation of the transformed URI, as per the + above CVE names.

+
+
+ diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c index a7fb0666d3..10aec8f3af 100644 --- a/modules/mappers/mod_rewrite.c +++ b/modules/mappers/mod_rewrite.c @@ -190,6 +190,7 @@ static const char* really_last_key = "rewrite_really_last"; #define OPTION_INHERIT 1<<1 #define OPTION_INHERIT_BEFORE 1<<2 #define OPTION_NOSLASH 1<<3 +#define OPTION_ANYURI 1<<4 #ifndef RAND_MAX #define RAND_MAX 32767 @@ -2893,6 +2894,9 @@ static const char *cmd_rewriteoptions(cmd_parms *cmd, "LimitInternalRecursion directive and will be " "ignored."); } + else if (!strcasecmp(w, "allowanyuri")) { + options |= OPTION_ANYURI; + } else { return apr_pstrcat(cmd->pool, "RewriteOptions: unknown option '", w, "'", NULL); @@ -4419,8 +4423,16 @@ static int hook_uri2file(request_rec *r) return DECLINED; } - if ((r->unparsed_uri[0] == '*' && r->unparsed_uri[1] == '\0') - || !r->uri || r->uri[0] != '/') { + /* Unless the anyuri option is set, ensure that the input to the + * first rule really is a URL-path, avoiding security issues with + * poorly configured rules. See CVE-2011-3368, CVE-2011-4317. */ + if ((dconf->options & OPTION_ANYURI) == 0 + && ((r->unparsed_uri[0] == '*' && r->unparsed_uri[1] == '\0') + || !r->uri || r->uri[0] != '/')) { + rewritelog((r, 8, NULL, "Declining, request-URI '%s' is not a URL-path. " + "Consult the manual entry for the RewriteOptions directive " + "for options and caveats about matching other strings.", + r->uri)); return DECLINED; }