On Tuesday 12 October 2010 19:49:02 Malte S. Stretz wrote: > On Tuesday 12 October 2010 18:13:46 William A. Rowe Jr. wrote: > > On 10/12/2010 10:06 AM, Dirk-Willem van Gulik wrote: > > > On 12 Oct 2010, at 15:30, Malte S. Stretz wrote: > > >> I had a quick look at the Apache source and the solution was > > >> simple: > > >> Just drop headers which contain any character outside the range > > >> > > >> [a-zA-Z0-9-]. The patch against trunk is attached. > > > > > > This made me think of something we had a while ago; and after > > > checking the logs - big +1 from me! > > > > Agreed, with a caviat... we aught to be able to toggle this for the > > rare but significant legacy app that requires it... which implies a > > per-dir flag that can override just one CGI script out of an entire > > server. > > I think an option is not needed as there is a workaround. Eg. to make > an Accept_Encoding header work: > > SetEnvIfNoCase ^Accept.Encoding$ ^(.*)$ fix_header=$1 > RequestHeader set Accept-Encoding %{fix_header}e env=fix_header >[...]
Attached is an updated patch which also updates the docs. It also includes the commit message I tried to commit it with (didn't realize that there are per-project commit flags). Is the documented workaround good enough or should something like an map- broken-headers environment variable be introduced? Cheers, Malte
Be more strict when mapping HTTP headers to env variables. While this prevents some potential cross-site-scripting attacks (cf. <http://events.ccc.de/congress/2007/Fahrplan/events/2212.en.html>) it might break some broken clients. This fact is documented in various places and a workaround is available in env.html. On the dev list it was suggested that instead of a workaround an option should be introduced. Please yell if thats the conensus. Somebody should proofread my English :) --This line, and those below, will be ignored-- M server/util_script.c M docs/manual/env.xml M docs/manual/new_features_2_4.xml M docs/manual/howto/cgi.xml Index: server/util_script.c =================================================================== --- server/util_script.c (revision 1023678) +++ server/util_script.c (working copy) @@ -67,11 +67,14 @@ *cp++ = '_'; while ((c = *w++) != 0) { - if (!apr_isalnum(c)) { + if (apr_isalnum(c)) { + *cp++ = apr_toupper(c); + } + else if (c == '-') { *cp++ = '_'; } else { - *cp++ = apr_toupper(c); + return NULL; } } *cp = 0; @@ -175,8 +178,8 @@ continue; } #endif - else { - apr_table_addn(e, http2env(r->pool, hdrs[i].key), hdrs[i].val); + else if ((env_temp = http2env(r->pool, hdrs[i].key)) != NULL) { + apr_table_addn(e, env_temp, hdrs[i].val); } } Index: docs/manual/env.xml =================================================================== --- docs/manual/env.xml (revision 1023678) +++ docs/manual/env.xml (working copy) @@ -140,6 +140,13 @@ not be a number. Characters which do not match this restriction will be replaced by an underscore when passed to CGI scripts and SSI pages.</li> + + <li>A special case are HTTP headers which are passed to CGI + scripts and the like via environment variables (see below). + They are converted to uppercase and only dashes are replaced with + underscores; if the header contains any other (invalid) character, + the whole header is silently dropped. See <a href="#fixheader"> + below</a> for a workaround.</li> <li>The <directive module="mod_env">SetEnv</directive> directive runs late during request processing meaning that directives such as @@ -423,6 +430,32 @@ <section id="examples"> <title>Examples</title> + <section id="fixheader"> + <title>Passing broken headers to CGI scripts</title> + + <p>Starting with version 2.4, Apache is more strict about how HTTP + headers are converted to environment variables in <module>mod_cgi + </module> and other modules: Previously any invalid characters + in header names were simply translated to underscores. This allowed + for some potential cross-site-scripting attacks via header injection + (see <a href="http://events.ccc.de/congress/2007/Fahrplan/events/2212.en.html"> + Unusual Web Bugs</a>, slide 19/20).</p> + + <p>If you have to support a client which sends broken headers and + which can't be fixed, a simple workaround involving <module>mod_setenvif + </module> and <module>mod_header</module> allows you to still accept + these headers:</p> + +<example><pre> +# +# The following works around a client sending a broken Accept_Encoding +# header. +# +SetEnvIfNoCase ^Accept.Encoding$ ^(.*)$ fix_accept_encoding=$1 +RequestHeader set Accept-Encoding %{fix_accept_encoding}e env=fix_accept_encoding</pre></example> + + </section> + <section id="misbehaving"> <title>Changing protocol behavior with misbehaving clients</title> Index: docs/manual/new_features_2_4.xml =================================================================== --- docs/manual/new_features_2_4.xml (revision 1023678) +++ docs/manual/new_features_2_4.xml (working copy) @@ -98,6 +98,15 @@ <dt><module>mod_allowmethods</module></dt> <dd>New module to restrict certain HTTP methods without interfering with authentication or authorization.</dd> + + <dt><module>mod_cgi</module>, <module>mod_include</module>, <module>mod_isapi</module>, ...</dt> + <dd>Translation of headers to environment variables is more strict than + before to mitigate some possible cross-site-scripting attacks via header + injection. Headers containing invalid characters (including underscores) + are now silently dropped. <a href="env.html">Environment Variables + in Apache</a> has some pointers on how to work around broken legacy + clients which require such headers. (This affects all modules which + use these environment variables.)</dd> </dl> </section> Index: docs/manual/howto/cgi.xml =================================================================== --- docs/manual/howto/cgi.xml (revision 1023678) +++ docs/manual/howto/cgi.xml (working copy) @@ -353,10 +353,21 @@ <p>Make sure that this is in fact the path to the interpreter.</p> - <p>In addition, if your CGI program depends on other <a + </section> + + <section id="missingenv"> + <title>Missing environment variables</title> + + <p>If your CGI program depends on non-standard <a href="#env">environment variables</a>, you will need to assure that those variables are passed by Apache.</p> - + + <p>When you miss HTTP headers from the environment, make + sure they are formatted according to + <a href="http://tools.ietf.org/html/rfc2616">RFC 2616</a>, + section 4.2: Header names must start with a letter, + followed only by letters, numbers or hyphen. Any header + violating this rule will be dropped silently.</p> </section> <section id="syntaxerrors">