You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ma...@hyperreal.org on 2000/02/02 19:02:53 UTC

cvs commit: apache-site/info/css-security apache_1.3.11_css_patch.txt apache_specific.html encoding_examples.html index.html

marc        00/02/02 10:02:51

  Added:       info/css-security apache_1.3.11_css_patch.txt
                        apache_specific.html encoding_examples.html
                        index.html
  Log:
  Added information about recently discovered cross site scripting security
  problem.
  
  Revision  Changes    Path
  1.1                  apache-site/info/css-security/apache_1.3.11_css_patch.txt
  
  Index: apache_1.3.11_css_patch.txt
  ===================================================================
  This patch is against Apache 1.3.11.  It may be updated as the situation
  warrants.
  
  Last updated: Wed Feb  2 01:09:23 MST 2000
  
  Index: htdocs/manual/mod/core.html
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/htdocs/manual/mod/core.html,v
  retrieving revision 1.162
  diff -u -r1.162 core.html
  --- core.html	2000/01/18 19:32:49	1.162
  +++ core.html	2000/02/02 07:59:17
  @@ -23,6 +23,8 @@
   <UL>
   <LI><A HREF="#accessconfig">AccessConfig</A>
   <LI><A HREF="#accessfilename">AccessFileName</A>
  +<LI><A HREF="#adddefaultcharset">AddDefaultCharset</A>
  +<LI><A HREF="#adddefaultcharsetname">AddDefaultCharsetName</A>
   <LI><A HREF="#addmodule">AddModule</A>
   <LI><A HREF="#allowoverride">AllowOverride</A>
   <LI><A HREF="#authname">AuthName</A>
  @@ -162,6 +164,42 @@
   &lt;Directory /&gt;<BR>
   AllowOverride None<BR>
   &lt;/Directory&gt;</CODE></BLOCKQUOTE><P><HR>
  +
  +<H2><A NAME="adddefaultcharset">AddDefaultCharset directive</A></H2>
  +<A HREF="directive-dict.html#Syntax" REL="Help"><STRONG>Syntax:</STRONG></A> 
  +AddDefaultCharset <EM>on / off</EM><BR>
  +<A HREF="directive-dict.html#Context" REL="Help" ><STRONG>Context:</STRONG></A> 
  +all<BR>
  +<A HREF="directive-dict.html#Status" REL="Help" ><STRONG>Status:</STRONG></A> 
  +core<BR>
  +<A HREF="directive-dict.html#Default" REL="Help"><STRONG>Default:</STRONG></A>
  +<CODE>AddDefaultCharset off</CODE><BR>
  +<A HREF="directive-dict.html#Compatibility" REL="Help"><STRONG>Compatibility:
  +</STRONG></A> AddDefaultCharset is only available in Apache 1.3.12 and later<P>
  +If enabled, any response that does not have any parameter on the content 
  +type in the HTTP headers will have a charset parameter added specifying 
  +the character set the client should use for the document.  This will 
  +override any character set specified in the body of the document via a 
  +<CODE>META</CODE> tag.  The character set added is specified by the 
  +<CODE>AddDefaultCharsetName</CODE> directive.
  +<P><HR>
  +
  +<H2><A NAME="adddefaultcharsetname">AddDefaultCharsetName directive</A></H2>
  +<A HREF="directive-dict.html#Syntax" REL="Help"><STRONG>Syntax:</STRONG></A> 
  +AddDefaultCharsetName <EM>charset</EM><BR>
  +<A HREF="directive-dict.html#Context" REL="Help" ><STRONG>Context:</STRONG></A> 
  +all<BR>
  +<A HREF="directive-dict.html#Status" REL="Help" ><STRONG>Status:</STRONG></A> 
  +core<BR>
  +<A HREF="directive-dict.html#Default" REL="Help"><STRONG>Default:</STRONG></A>
  +<CODE>AddDefaultCharsetName iso-8859-1</CODE><BR>
  +<A HREF="directive-dict.html#Compatibility" REL="Help"><STRONG>Compatibility:
  +</STRONG></A> AddDefaultCharsetName is only available in Apache 1.3.12 and 
  +later<P>
  +This directive specifies the name of the character set that will be added
  +if the <A HREF="#adddefaultcharset">AddDefaultCharset</A> directive is 
  +enabled.
  +<P><HR>
   
   <H2><A NAME="addmodule">AddModule directive</A></H2>
   <!--%plaintext &lt;?INDEX {\tt AddModule} directive&gt; -->
  Index: htdocs/manual/mod/directives.html
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/htdocs/manual/mod/directives.html,v
  retrieving revision 1.60
  diff -u -r1.60 directives.html
  --- directives.html     1999/12/19 16:34:32     1.60
  +++ directives.html     2000/02/02 08:09:07
  @@ -30,6 +30,9 @@
   <LI><A HREF="mod_autoindex.html#addalt">AddAlt</A>
   <LI><A HREF="mod_autoindex.html#addaltbyencoding">AddAltByEncoding</A>
   <LI><A HREF="mod_autoindex.html#addaltbytype">AddAltByType</A>
  +<LI><A HREF="mod_mime.html#addcharset">AddCharset</A>
  +<LI><A HREF="core.html#adddefaultcharset">AddDefaultCharset</A>
  +<LI><A HREF="core.html#adddefaultcharsetname">AddDefaultCharsetName</A>
   <LI><A HREF="mod_autoindex.html#adddescription">AddDescription</A>
   <LI><A HREF="mod_mime.html#addencoding">AddEncoding</A>
   <LI><A HREF="mod_mime.html#addhandler">AddHandler</A>
  Index: htdocs/manual/mod/mod_include.html
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/htdocs/manual/mod/mod_include.html,v
  retrieving revision 1.23
  diff -u -r1.23 mod_include.html
  --- mod_include.html	1998/09/17 12:06:40	1.23
  +++ mod_include.html	2000/02/02 07:59:18
  @@ -89,15 +89,34 @@
   routine when printing dates.
   </DL>
   
  +<A NAME="echo">
   <DT><STRONG>echo</STRONG>
   <DD>
   This command prints one of the include variables, defined below.
   If the variable is unset, it is printed as <CODE>(none)</CODE>.
   Any dates printed are subject to the currently configured <CODE>timefmt</CODE>.
  +
   Attributes:
   <DL>
   <DT>var
   <DD>The value is the name of the variable to print.
  +<DT>encoding 
  +<DD>Specifies how Apache should encode special characters contained
  +in the variable before outputting them.  If set to "none", no encoding
  +will be done.  If set to "url", then URL encoding (also known as
  +%-encoding; this is appropriate for use within URLs in links, etc.)
  +will be performed.  At the start of an <CODE>echo</CODE> element,
  +the default is set to "entity", resulting in entity encoding (which
  +is appropriate in the context of a block-level HTML element, eg.
  +a paragraph of text).  This can be changed by adding an
  +<CODE>encoding</CODE> attribute, which will remain in effect until
  +the next <CODE>encoding</CODE> attribute is encountered or the
  +element ends, whichever comes first.  Note that only special
  +characters as defined in the ISO-8859-1 character encoding will be
  +encoded.  This encoding process may not have the desired result if
  +a different character encoding is in use.  Apache 1.3.12 and above; previous
  +versions do no encoding.
  +
   </DL>
   
   <DT><STRONG>exec</STRONG>
  @@ -181,7 +200,9 @@
   
   <DT><STRONG>printenv</STRONG>
   <DD>This prints out a listing of all existing variables and their values.
  -    No attributes.
  +   Starting with Apache 1.3.12, special characters are entity encoded (see the 
  +   <A HREF="#echo"><CODE>echo</CODE></A> element for details) before being
  +   output.  No attributes.
   <DD>For example: <CODE>&lt;!--#printenv --&gt;</CODE>
   <DD>Apache 1.2 and above.
   
  Index: src/CHANGES
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v
  retrieving revision 1.1502
  diff -u -r1.1502 CHANGES
  --- CHANGES     2000/01/18 17:12:13     1.1502
  +++ CHANGES     2000/02/02 08:09:11
  @@ -1,3 +1,31 @@
  +Changes with Apache 1.3.12
  +
  +  *) Add an explicit charset=iso-8859-1 to pages generated by
  +     ap_send_error_response(), such as the default 404 page.
  +     [Marc Slemko]
  +
  +  *) Add the AddDefaultCharset and AddDefaultCharsetName directives.  
  +     These allow you to tell Apache to specify the given character
  +     set on any document that does not have one explicitly specified in 
  +     the headers.  [Marc Slemko]
  +
  +  *) Properly escape various messages output to the client from a number
  +     of modules and places in the core code.  [Marc Slemko]
  +
  +  *) Change mod_actions, mod_autoindex, mod_expires, and mod_log_config to
  +     not consider any parameters such as charset when making decisions 
  +     based on content type.  This does remove some functionality for 
  +     some users, but means that when these modules are configured to do 
  +     particular things with particular MIME types, the charset should 
  +     not be included.  A better way of addressing this for users who 
  +     want to set things on a per charset basis is necessary in the future.  
  +     [Marc Slemko]
  +
  +  *) mod_include now entity encodes output from "printenv" and "echo var"
  +     by default.  The encoding for "echo var" can be set to URL encoding
  +     or no encoding using the new "encoding" attribute to the echo tag.
  +     [Marc Slemko]
  +
   Changes with Apache 1.3.11
   
     *) MPE builds are no longer stripped, which caused the executable
  Index: src/include/http_core.h
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/include/http_core.h,v
  retrieving revision 1.59
  diff -u -r1.59 http_core.h
  --- http_core.h	1999/06/28 22:38:25	1.59
  +++ http_core.h	2000/02/02 07:59:24
  @@ -243,6 +243,15 @@
        */
       unsigned d_is_fnmatch : 1;
   
  +    /* should we force a charset on any outgoing parameterless content-type?
  +     * if so, which charset?
  +     */
  +#define ADD_DEFAULT_CHARSET_OFF   (0)
  +#define ADD_DEFAULT_CHARSET_ON    (1)
  +#define ADD_DEFAULT_CHARSET_UNSET (2)
  +    unsigned add_default_charset : 2;
  +    char *add_default_charset_name;
  +
       /* System Resource Control */
   #ifdef RLIMIT_CPU
       struct rlimit *limit_cpu;
  Index: src/include/httpd.h
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/include/httpd.h,v
  retrieving revision 1.303
  diff -u -r1.303 httpd.h
  --- httpd.h	2000/01/30 19:46:11	1.303
  +++ httpd.h	2000/02/02 07:59:24
  @@ -409,6 +409,12 @@
   #endif /* default limit on number of request header fields */
   
   /*
  + * The default default character set name to add if AddDefaultCharset is 
  + * enabled.  Overridden with AddDefaultCharsetName.
  + */
  +#define DEFAULT_ADD_DEFAULT_CHARSET_NAME "iso-8859-1"
  +
  +/*
    * The below defines the base string of the Server: header. Additional
    * tokens can be added via the ap_add_version_component() API call.
    *
  Index: src/main/http_core.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/main/http_core.c,v
  retrieving revision 1.277
  diff -u -r1.277 http_core.c
  --- http_core.c	2000/01/11 14:13:40	1.277
  +++ http_core.c	2000/02/02 07:59:25
  @@ -154,6 +154,9 @@
   
       conf->server_signature = srv_sig_unset;
   
  +    conf->add_default_charset = ADD_DEFAULT_CHARSET_UNSET;
  +    conf->add_default_charset_name = DEFAULT_ADD_DEFAULT_CHARSET_NAME;
  +
       return (void *)conf;
   }
   
  @@ -281,6 +284,14 @@
   	conf->server_signature = new->server_signature;
       }
   
  +    if (new->add_default_charset != ADD_DEFAULT_CHARSET_UNSET) {
  +	conf->add_default_charset = new->add_default_charset;
  +    }
  +
  +    if (new->add_default_charset_name) {
  +	conf->add_default_charset_name = new->add_default_charset_name;
  +    }
  +
       return (void*)conf;
   }
   
  @@ -1035,6 +1046,28 @@
   }
   #endif /*GPROF*/
   
  +static const char *set_add_default_charset(cmd_parms *cmd, 
  +	core_dir_config *d, int arg)
  +{
  +    const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT);
  +    if (err != NULL) {
  +        return err;
  +    }
  +    d->add_default_charset = arg != 0;
  +    return NULL;
  +}
  +
  +static const char *set_add_default_charset_name(cmd_parms *cmd, 
  +	core_dir_config *d, char *arg)
  +{
  +    const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT);
  +    if (err != NULL) {
  +        return err;
  +    }
  +    d->add_default_charset_name = arg;
  +    return NULL;
  +}
  +
   static const char *set_document_root(cmd_parms *cmd, void *dummy, char *arg)
   {
       void *sconf = cmd->server->module_config;
  @@ -2786,6 +2819,10 @@
   { "GprofDir", set_gprof_dir, NULL, RSRC_CONF, TAKE1,
     "Directory to plop gmon.out files" },
   #endif
  +{ "AddDefaultCharset", set_add_default_charset, NULL, OR_FILEINFO, FLAG,
  +  "whether or not to add a default charset to any Content-Type without one" },
  +{ "AddDefaultCharsetName", set_add_default_charset_name, NULL, OR_FILEINFO, 
  +  TAKE1, "The name of the charset to add if AddDefaultCharset is enabled" },
   
   /* Old resource config file commands */
     
  Index: src/main/http_log.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/main/http_log.c,v
  retrieving revision 1.82
  diff -u -r1.82 http_log.c
  --- http_log.c	2000/01/31 22:24:07	1.82
  +++ http_log.c	2000/02/02 07:59:25
  @@ -487,7 +487,8 @@
       if (((level & APLOG_LEVELMASK) <= APLOG_WARNING)
   	&& (ap_table_get(r->notes, "error-notes") == NULL)) {
   	ap_table_setn(r->notes, "error-notes",
  -		      ap_pvsprintf(r->pool, fmt, args));
  +		      ap_escape_html(r->pool, ap_pvsprintf(r->pool, fmt, 
  +		      args)));
       }
       va_end(args);
   }
  Index: src/main/http_protocol.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/main/http_protocol.c,v
  retrieving revision 1.286
  diff -u -r1.286 http_protocol.c
  --- http_protocol.c	2000/01/11 14:13:41	1.286
  +++ http_protocol.c	2000/02/02 07:59:28
  @@ -103,6 +103,35 @@
   
   #endif /*CHARSET_EBCDIC*/
   
  +/*
  + * Builds the content-type that should be sent to the client from the
  + * content-type specified.  The following rules are followed:
  + *    - if type is NULL, type is set to ap_default_type(r)
  + *    - if charset adding is disabled, stop processing and return type.
  + *    - then, if there are no parameters on type, add the default charset
  + *    - return type
  + */
  +static const char *make_content_type(request_rec *r, const char *type) {
  +    const char *i;
  +    core_dir_config *conf = (core_dir_config *)ap_get_module_config(
  +	r->per_dir_config, &core_module);
  +    if (!type) type = ap_default_type(r);
  +    if (conf->add_default_charset != ADD_DEFAULT_CHARSET_ON) return type;
  +
  +    i = type;
  +    while (*i && *i != ';') i++;
  +    if (*i && *i == ';') {
  +	/* already has parameter, do nothing */
  +	/* XXX should check for actual charset=, but then we need real 
  +	 * parsing code 
  +	 */
  +    } else {
  +	type = ap_pstrcat(r->pool, type, "; charset=", 
  +	    conf->add_default_charset_name, NULL);
  +    }
  +    return type;
  +}
  +
   static int parse_byterange(char *range, long clength, long *start, long *end)
   {
       char *dash = strchr(range, '-');
  @@ -265,7 +294,7 @@
       }
   
       if (r->byterange > 1) {
  -        const char *ct = r->content_type ? r->content_type : ap_default_type(r);
  +        const char *ct = make_content_type(r, r->content_type);
           char ts[MAX_STRING_LEN];
   
           ap_snprintf(ts, sizeof(ts), "%ld-%ld/%ld", range_start, range_end,
  @@ -1636,10 +1665,8 @@
           ap_table_setn(r->headers_out, "Content-Type",
                     ap_pstrcat(r->pool, "multipart", use_range_x(r) ? "/x-" : "/",
                             "byteranges; boundary=", r->boundary, NULL));
  -    else if (r->content_type)
  -        ap_table_setn(r->headers_out, "Content-Type", r->content_type);
  -    else
  -        ap_table_setn(r->headers_out, "Content-Type", ap_default_type(r));
  +    else ap_table_setn(r->headers_out, "Content-Type", make_content_type(r, 
  +	r->content_type));
   
       if (r->content_encoding)
           ap_table_setn(r->headers_out, "Content-Encoding", r->content_encoding);
  @@ -2550,7 +2577,7 @@
           r->content_languages = NULL;
           r->content_encoding = NULL;
           r->clength = 0;
  -        r->content_type = "text/html";
  +        r->content_type = "text/html; charset=iso-8859-1";
   
           if ((status == METHOD_NOT_ALLOWED) || (status == NOT_IMPLEMENTED))
               ap_table_setn(r->headers_out, "Allow", make_allow(r));
  Index: src/main/util.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/main/util.c,v
  retrieving revision 1.176
  diff -u -r1.176 util.c
  --- util.c	2000/01/12 20:57:48	1.176
  +++ util.c	2000/02/02 07:59:29
  @@ -127,6 +127,8 @@
   {
       const char *semi;
   
  +    if (intype == NULL) return NULL;
  +
       semi = strchr(intype, ';');
       if (semi == NULL) {
   	return ap_pstrdup(p, intype);
  Index: src/modules/proxy/proxy_util.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/modules/proxy/proxy_util.c,v
  retrieving revision 1.83
  diff -u -r1.83 proxy_util.c
  --- proxy_util.c	2000/01/11 14:13:47	1.83
  +++ proxy_util.c	2000/02/02 07:59:29
  @@ -844,9 +844,12 @@
       ap_table_setn(r->notes, "error-notes",
   		  ap_pstrcat(r->pool, 
   			     "The proxy server could not handle the request "
  -			     "<EM><A HREF=\"", r->uri, "\">",
  -			     r->method, "&nbsp;", r->uri, "</A></EM>.<P>\n"
  -			     "Reason: <STRONG>", message, "</STRONG>", NULL));
  +			     "<EM><A HREF=\"", ap_escape_uri(r->pool, r->uri),
  +			     "\">", r->method, "&nbsp;", 
  +			     ap_escape_html(r->pool, r->uri), "</A></EM>.<P>\n"
  +			     "Reason: <STRONG>",
  +			     ap_escape_html(r->pool, message), 
  +			     "</STRONG>", NULL));
   
       /* Allow the "error-notes" string to be printed by ap_send_error_response() */
       ap_table_setn(r->notes, "verbose-error-to", ap_pstrdup(r->pool, "*"));
  Index: src/modules/standard/mod_actions.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/modules/standard/mod_actions.c,v
  retrieving revision 1.33
  diff -u -r1.33 mod_actions.c
  --- mod_actions.c	2000/01/11 14:23:03	1.33
  +++ mod_actions.c	2000/02/02 07:59:30
  @@ -195,7 +195,8 @@
   {
       action_dir_config *conf = (action_dir_config *)
           ap_get_module_config(r->per_dir_config, &action_module);
  -    const char *t, *action = r->handler ? r->handler : r->content_type;
  +    const char *t, *action = r->handler ? r->handler : 
  +	ap_field_noparam(r->pool, r->content_type);
       const char *script;
       int i;
   
  Index: src/modules/standard/mod_autoindex.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/modules/standard/mod_autoindex.c,v
  retrieving revision 1.113
  diff -u -r1.113 mod_autoindex.c
  --- mod_autoindex.c	1999/12/31 05:35:52	1.113
  +++ mod_autoindex.c	2000/02/02 07:59:30
  @@ -732,7 +732,7 @@
   
   static char *find_item(request_rec *r, array_header *list, int path_only)
   {
  -    const char *content_type = r->content_type;
  +    const char *content_type = ap_field_noparam(r->pool, r->content_type);
       const char *content_encoding = r->content_encoding;
       char *path = r->filename;
   
  Index: src/modules/standard/mod_expires.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/modules/standard/mod_expires.c,v
  retrieving revision 1.33
  diff -u -r1.33 mod_expires.c
  --- mod_expires.c	1999/10/21 20:45:26	1.33
  +++ mod_expires.c	2000/02/02 07:59:30
  @@ -437,7 +437,8 @@
       if (r->content_type == NULL)
           code = NULL;
       else
  -        code = (char *) ap_table_get(conf->expiresbytype, r->content_type);
  +        code = (char *) ap_table_get(conf->expiresbytype, 
  +		ap_field_noparam(r->pool, r->content_type));
   
       if (code == NULL) {
           /* no expires defined for that type, is there a default? */
  Index: src/modules/standard/mod_include.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/modules/standard/mod_include.c,v
  retrieving revision 1.121
  diff -u -r1.121 mod_include.c
  --- mod_include.c	1999/12/31 05:35:52	1.121
  +++ mod_include.c	2000/02/02 07:59:30
  @@ -922,7 +922,10 @@
   {
       char tag[MAX_STRING_LEN];
       char *tag_val;
  +    enum {E_NONE, E_URL, E_ENTITY} encode;
   
  +    encode = E_ENTITY;
  +
       while (1) {
           if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
               return 1;
  @@ -931,7 +934,15 @@
               const char *val = ap_table_get(r->subprocess_env, tag_val);
   
               if (val) {
  -                ap_rputs(val, r);
  +		if (encode == E_NONE) {
  +		    ap_rputs(val, r);
  +		}
  +		else if (encode == E_URL) {
  +		    ap_rputs(ap_escape_uri(r->pool, val), r);
  +		}
  +		else if (encode == E_ENTITY) {
  +		    ap_rputs(ap_escape_html(r->pool, val), r);
  +		}
               }
               else {
                   ap_rputs("(none)", r);
  @@ -940,6 +951,19 @@
           else if (!strcmp(tag, "done")) {
               return 0;
           }
  +	else if (!strcmp(tag, "encoding")) {
  +	    if (!strcasecmp(tag_val, "none")) encode = E_NONE;
  +	    else if (!strcasecmp(tag_val, "url")) encode = E_URL;
  +	    else if (!strcasecmp(tag_val, "entity")) encode = E_ENTITY;
  +	    else {
  +		ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
  +			    "unknown value \"%s\" to parameter \"encoding\" of "
  +			    "tag echo in %s",
  +			    tag_val, r->filename);
  +		ap_rputs(error, r);
  +	    }
  +	}
  +
           else {
               ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
                           "unknown parameter \"%s\" to tag echo in %s",
  @@ -2116,7 +2140,8 @@
       }
       else if (!strcmp(tag, "done")) {
           for (i = 0; i < arr->nelts; ++i) {
  -            ap_rvputs(r, elts[i].key, "=", elts[i].val, "\n", NULL);
  +            ap_rvputs(r, ap_escape_html(r->pool, elts[i].key), "=", 
  +		ap_escape_html(r->pool, elts[i].val), "\n", NULL);
           }
           return 0;
       }
  Index: src/modules/standard/mod_log_config.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/modules/standard/mod_log_config.c,v
  retrieving revision 1.80
  diff -u -r1.80 mod_log_config.c
  --- mod_log_config.c	1999/12/15 23:04:22	1.80
  +++ mod_log_config.c	2000/02/02 07:59:30
  @@ -391,7 +391,7 @@
   {
       const char *cp = ap_table_get(r->headers_out, a);
       if (!strcasecmp(a, "Content-type") && r->content_type) {
  -        cp = r->content_type;
  +        cp = ap_field_noparam(r->pool, r->content_type);
       }
       if (cp) {
           return cp;
  Index: src/modules/standard/mod_status.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/modules/standard/mod_status.c,v
  retrieving revision 1.110
  diff -u -r1.110 mod_status.c
  --- mod_status.c	2000/01/12 15:55:02	1.110
  +++ mod_status.c	2000/02/02 07:59:31
  @@ -597,9 +597,10 @@
   			format_byte_out(r, bytes);
   			ap_rputs(")\n", r);
   			ap_rprintf(r, " <i>%s {%s}</i> <b>[%s]</b><br>\n\n",
  -			    score_record.client,
  +			    ap_escape_html(r->pool, score_record.client),
   			    ap_escape_html(r->pool, score_record.request),
  -			    vhost ? vhost->server_hostname : "(unavailable)");
  +			    vhost ? ap_escape_html(r->pool, 
  +				vhost->server_hostname) : "(unavailable)");
   		    }
   		    else {		/* !no_table_report */
   			if (score_record.status == SERVER_DEAD)
  @@ -671,8 +672,9 @@
   			else
   			    ap_rprintf(r,
   			     "<td>%s<td nowrap>%s<td nowrap>%s</tr>\n\n",
  -			     score_record.client,
  -			     vhost ? vhost->server_hostname : "(unavailable)",
  +			     ap_escape_html(r->pool, score_record.client),
  +			     vhost ? ap_escape_html(r->pool, 
  +				vhost->server_hostname) : "(unavailable)",
   			     ap_escape_html(r->pool, score_record.request));
   		    }		/* no_table_report */
   		}			/* !short_report */
  
  
  
  1.1                  apache-site/info/css-security/apache_specific.html
  
  Index: apache_specific.html
  ===================================================================
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
  <HTML>
   <HEAD>
    <TITLE>Cross Site Scripting Info: Apache Specific</TITLE>
   </HEAD>
  
   <!-- Background white, links blue (unvisited), navy (visited), red (active) -->
   <BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#000080" 
         ALINK="#FF0000">
    <DIV ALIGN="CENTER">
     <IMG SRC="../../images/apache_sub.gif" ALT="[APACHE DOCUMENTATION]">
    </DIV>
    <H1 ALIGN="CENTER">Cross Site Scripting Info: Apache Specific</H1>
  
  <H2>Introduction:</H2>
  
  <P>While reviewing the Apache code for any problems related to this
  problem, we have discovered a number of issues.  Many of them are
  not bugs in Apache, but are places where Apache can do more to
  avoid being vulnerable to the Cross Site Scriptint security problem.
  None of the changes fix any security holes in Apache itself that
  can compromise the server directly, but are focused towards its
  interaction with clients.
  
  <P>Included below is a summary of the current known issues and
  fixes, where available.  This information will be expanded on as
  information becomes available and time permits.
  
  <H2>Issues outstanding:</H2>
  <UL>
  
  <LI>Older versions of the <CODE>printenv</CODE> CGI script distributed with
  Apache did not properly encode their output.  If you have one of these on
  your system, and this issue impacts your site, you should disable the CGI.
  
  <LI>Current versions of <CODE>printenv</CODE> and <CODE>test-cgi</CODE>
  send content with a MIME type of text/plain, meaning that no encoding
  is required or possible.  This was changed effective in Apache
  1.3.11 to fix the problem of <CODE>printenv</CODE> not properly
  encoding its output.  Unfortunately, Microsoft Internet Explorer
  does not respect that MIME type, and incorrectly processes the
  output as HTML that is what it guesses it to be.  This security
  problem has been reported to Microsoft.  At this time, the recommended
  workaround is to simply remove the <CODE>printenv</CODE> and
  <CODE>test-cgi</CODE> scripts from your site if this issue impacts
  you.
  
  <LI>If you do have other legitimate text/plain content on your site
  that is generated based on user input, you may need to configure
  your server to prevent IE from accessing it or change it to text/html
  so you can encode it.  Alternatively, you can filter special
  characters if that is possible in your situation.  Thankfully, this
  only impacts a very few sites.
  
  <LI>A number of Apache modules such as <CODE>mod_status</CODE> do not
  set an explicit character set on their output.  Using the AddDefaultCharset
  directive will work around this.  The modules that don't set an explicit
  character set are not normally accessible to users and they are not 
  thought to pose a significant risk.
  
  <LI>What is necessary to ensure that sites that legitimately use character
  sets with different encodings of special characters, such as UTF-7, are 
  protected?  How can Apache facilitate this?  This is a major issue for 
  those with a significant amount of content in character sets other than
  iso-8859-1.
  
  
  </UL>
  
  <H2>Fixes from CHANGES file:</H2>
  <P>These will be expanded on as time permits.  These patches are available
  in the current <A HREF="apache_1.3.11_css_patch.txt">Apache patch</A> 
  against Apache 1.3.11.
  
  <PRE>
    *) Add an explicit charset=iso-8859-1 to pages generated by
       ap_send_error_response(), such as the default 404 page.
       [Marc Slemko]
  
    *) Add the AddDefaultCharset and AddDefaultCharsetName directives.
       These allow you to tell Apache to specify the given character
       set on any document that does not have one explicitly specified in
       the headers.  [Marc Slemko]
  
    *) Properly escape various messages output to the client from a number
       of modules and places in the core code.  [Marc Slemko]
  
    *) Change mod_actions, mod_autoindex, mod_expires, and mod_log_config to
       not consider any parameters such as charset when making decisions
       based on content type.  This does remove some functionality for
       some users, but means that when these modules are configured to do
       particular things with particular MIME types, the charset should
       not be included.  A better way of addressing this for users who
       want to set things on a per charset basis is necessary in the future.
       [Marc Slemko]
  
    *) mod_include now entity encodes output from "printenv" and "echo var"
       by default.  The encoding for "echo var" can be set to URL encoding
       or no encoding using the new "encoding" attribute to the echo tag.
       [Marc Slemko]
  
  </PRE>
  
  </BODY>
  </HTML>
  
  
  
  1.1                  apache-site/info/css-security/encoding_examples.html
  
  Index: encoding_examples.html
  ===================================================================
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
  <HTML>
   <HEAD>
    <TITLE>Cross Site Scripting Info: Encoding Examples</TITLE>
   </HEAD>
  
   <!-- Background white, links blue (unvisited), navy (visited), red (active) -->
   <BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#000080" 
         ALINK="#FF0000">
    <DIV ALIGN="CENTER">
     <IMG SRC="../../images/apache_sub.gif" ALT="[APACHE DOCUMENTATION]">
    </DIV>
    <H1 ALIGN="CENTER">Cross Site Scripting Info: Encoding Examples</H1>
  
  <H2>Introduction:</H2>
  
  <P>We trust you are already familiar with the Cross Site Scripting
  security problem and the concept behind how it works.  If not, see
  the <A HREF="http://www.cert.org/advisories/CA-2000-02.html">CERT
  Advisory CA-2000-02</A> that has been released on this issue for 
  details before continuing.
  
  <P>This document focuses on how you can safely encode data before 
  it is output to the client.  The main method of doing this is through
  entity encoding, as described in the CERT advisory, using entities
  such as "&amp;lt;".
  
  <H2>General Comments on Encoding:</H2>
  
  <P>Note that, in general, many functions that perform entity encoding
  do so in a way which is only suitable for use outside attribute
  values, in normal block level elements such as a paragraph of text.
  Many of the functions referenced below are in this category.  This
  means they may not encode characters such as the double or single
  quote.  If you don't use quotation marks around an attribute value
  supplied from user input, then you need to encode even more
  characters.  Always use quotes and you won't have to worry about
  that particular issue.
  
  <P>Unfortunately, the situation for encoding data within attribute
  values or within the body scripts (eg. within "&lt;SCRIPT&gt;"
  tags) is more complex and less understood.  If you are in this 
  situation, you may be wise to consider filtering special characters
  (as described in the <A
  HREF="http://www.cert.org/tech_tips/malicious_code_mitigation.html">CERT
  Tech Tip</A>) instead of encoding them.  Generally, encoding is 
  recommended because it does not require you to make a decision about
  what characters could legitimately be entered and need to be passed
  through and it has less of an impact on existing functionality.  
  
  <P>The reason why safely encoding data within attribute values is 
  difficult is because some characters that are not considered special
  characters can be arranged to have unexpected effects in certain
  attribute values.  This is very specific to the tag the attribute
  is associated with and to how the client interprets it.  For example,
  if you let the user enter the value for a HREF attribute, and you
  encode it properly, you could end up outputting a tag such as:
  
  <PRE>
  &lt;A HREF="javascript:document.writeln(document.cookie + &amp;quot;&amp;lt;BR&amp;gt;&amp;quot;)"&gt;
  </PRE>
  
  Even though you have properly encoded special characters, many popular
  browsers will interpret a "javascript:" URL as containing JavaScript
  to execute in the context of the current document.
  
  <P>One of the issues that is still unresolved is exactly what HTML 
  tags are "safe" to allow through, and what the algorithm for doing so
  is like.  Many sites wish to allow users to enter a limited subset
  of "safe" HTML.  This is still very much an open issue.  It has been 
  an issue for quite some time, and it is our hope that this Cross Site
  Scripting problem will help prompt more work into addressing it.
  
  <P>If you are encoding user entered data in a URL, then URL encoding (also
  known as percent encoding) is appropriate.  Unfortunately, this can be
  a complex thing to get right because the special characters in "http://",
  for example, must remain unencoded because they are part of the syntax
  of the URL.  Better solutions to deal with this are necessary.
  
  <P>Also note that some URL encoding functions encode a space into a "+" for
  historical reasons.  This will only work in the query string for CGIs, and
  will not properly encode a space in other parts of the URL.
  
  <P>We realize that all these special situations and the lack of a single
  bulletproof set of steps for encoding user data, wherever it may occur on 
  the page, makes the task of fixing this problem quite challenging in some
  cases.  We wish we had a better answer, and are working on filling in the
  fuzzy areas.
  
  <H2>PHP Example:</H2>
  
  <PRE>
  &lt;?
  $Text = "foo&lt;b&gt;bar";
  $URL = "foo&lt;b&gt;bar.html";
  echo HTMLSpecialChars($Text), "&lt;BR&gt;";     
  echo "&lt;A HREF=\"", rawurlencode($URL), "\"&gt;link&lt;/A&gt;";
  ?&gt;
  </PRE>
  
  <P>Note that PHP also has a strip_tags() function that will remove all 
  HTML tags from a string.  Using this function in a manner such as:
  
  <PRE>
  	echo strip_tags($Text);
  </PRE>
  
  will strip all HTML from the input.  However, if you use it in the form:
  
  <PRE>
  	echo strip_tags($Text, "&lt;B&gt;");
  </PRE>
  
  which only allows the "&lt;B&gt;" tag through, you are still often
  vulnerable to users inserting script code.  By design, this function
  does not strip attributes from the tags.  This means it is often
  possible to include things such as JavaScript event attributes.
  An example of a tag that would be allowed by the above strip_tags()
  call is:
  
  <PRE>
  	&lt;B onmouseover="document.location='http://www.cert.org/'"&gt;
  </PRE>
  
  <P>Some clients accept such attributes on tags that are otherwise benign.
  
  <H2>Apache Module Example:</H2>
  
  <PRE>
  char *Text = "foo&lt;b&gt;bar";
  char *URL = "foo&lt;b&gt;bar.html";
  ap_rvputs(r, ap_escape_html(r->pool, Text), "&lt;BR&gt;", NULL);
  ap_rvputs(r, "&lt;A HREF=\"", ap_escape_uri(r->pool, URL), "\"&gt;link&lt;/A&gt;", NULL);
  </PRE>
  
  <H2>mod_perl Example:</H2>
  
  <PRE>
  $Text = "foo&lt;b&gt;bar";
  $URL = "foo&lt;b&gt;bar.html";
  $r-&gt;print(Apache::Util::escape_html($Text), "&lt;BR&gt;");
  $r-&gt;print("&lt;A HREF=\"", Apache::Util::escape_html($URL), "\"&gt;link&lt;/A&gt;");
  </PRE>
  
  <P>This uses the same functions as in the Apache Module Example, called
  from Perl instead of directly from C.
  
  <H2>Perl Example:</H2>
  
  <PRE>
  use CGI ();
  $Text = "foo&lt;b&gt;bar";
  $URL = "foo&lt;b&gt;bar.html";
  print CGI::escapeHTML($Text), "&lt;BR&gt;";
  print qq(&lt;A HREF="), CGI::escape($URL), qq("&gt;link&lt;/A&gt;);
  </PRE>
  
  <P>Note that if you use the CGI.pm module in its full intended role,
  instead of just using helper functions from it, it will automatically 
  encode special characters in many places.  Unfortunately, this is yet
  again likely not sufficient in all situations.  See the documentation at 
  <A HREF="http://stein.cshl.org/WWW/software/CGI/">
  http://stein.cshl.org/WWW/software/CGI/</A> for more details on what
  this module can do.
  
   </BODY>
  </HTML>
  
  
  
  1.1                  apache-site/info/css-security/index.html
  
  Index: index.html
  ===================================================================
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
  <HTML>
   <HEAD>
    <TITLE>Cross Site Scripting Info</TITLE>
   </HEAD>
  
   <!-- Background white, links blue (unvisited), navy (visited), red (active) -->
   <BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#000080" 
         ALINK="#FF0000">
    <DIV ALIGN="CENTER">
     <IMG SRC="../../images/apache_sub.gif" ALT="[APACHE DOCUMENTATION]">
    </DIV>
    <H1 ALIGN="CENTER">Cross Site Scripting Info</H1>
  <CENTER>Last Modified: <!--#flastmod file="index.html"--></CENTER>
  
  <H2>Introduction:</H2>
  
  <P>This page contains information about the Cross Site Scripting
  security issue, how it impacts Apache itself, and how to properly 
  protect against it when using Apache related technologies.
  
  <P>For an overview of the issue, please see the <A 
  HREF="http://www.cert.org/advisories/CA-2000-02.html">CERT Advisory 
  CA-2000-02</A> that has been released on the issue.  You should 
  also review their related <A 
  HREF="http://www.cert.org/tech_tips/malicious_code_mitigation.html">
  Understanding Malicious Content Mitigation For Web Developers</A> tech
  tips document.  The CERT advisory also contains links to a number of 
  documents that Microsoft has put out on the issue which are also worth
  reviewing if this issue impacts you.  The information contained in 
  these documents will not be repeated here; this information assumes you
  have read these documents and are familiar with the issue.
  
  <P>We would like to emphasize that this is <B>not</B> an attack
  against any specific bug in a specific piece of software.  It is
  not an Apache problem.  It is not a Microsoft problem.  It is not
  a Netscape problem.  In fact, it isn't even a problem that can be
  clearly defined to be a server problem or a client problem.  It is
  an issue that is truly cross platform and is the result of unforeseen
  and unexpected interactions between various components of a set of 
  interconnected complex systems.  
  
  <P>There are specific bugs in a wide range of web server products,
  including Apache, that allow for or contribute to the exploitation
  of this security problem.  These bugs should not be there and
  need to be fixed.  But it is critical to realize that this is only
  a tiny part of the total issue.  The most serious issue is in all
  the site specific code that generates dynamic content.  We are
  bringing you this information to educate you on the issues that
  have been discovered in Apache that are related to this security
  problem but, more importantly, help educate you on how this may
  impact your own local code developed using Apache related technologies
  and how you can fix it.
  
  <P>There is no "golden bullet" patch that server or client vendors
  can release that will magically fix this issue across all web
  servers or clients using that product.
  
  <P>We would also like to point out that it is important to 
  understand that this is not the old, well known issue, that if a site
  allows user A to submit content that is viewed by user B, it has to 
  be properly encoded.  This vulnerability is when the content is both
  submitted and viewed strictly by user A.  Due to the difficulty of 
  properly encoding output in all situations, many sites do not worry
  about encoding data that is only shown to the user that sent the data
  in their request due to the mistaken assumption that this doesn't pose
  a security threat.
  
  <H2>Does this impact my web site?</H2>
  
  <P>This is a serious security issue, with potential implications
  that are only starting to be understood.  However, it is critical
  to realize that this problem does not expose any way to break into
  the server itself.  What it allows is for malicious attackers to
  potentially take control of the interaction between a user and a
  website.  If your website contains entirely static content with
  all information being publicly accessible, an attacker can gain
  very little from taking over this interaction.  It is likely that the
  most serious thing that an attacker can potentially do in this situation
  is change how a page appears to a particular user.
  
  <P>The sites where this poses the most potential danger are sites
  where users have some type of account or login and where they can
  perform actions with real world implications or access data that
  should not be publicly available.  This security problem poses a
  serious threat to such sites; it isn't necessary to break into the
  server to take control of a site if instead you can gain access on
  the user's end of things.
  
  <H2>Ok, where is the Apache related information?</H2>
  
  <P>Right here:
  
  <UL>
  <LI><A HREF="apache_specific.html">Apache HTTP server specific information</A>
  
  <LI>Current <A HREF="apache_1.3.11_css_patch.txt">Apache patch</A> against
  1.3.11 that addresses the known issues in Apache and provides some help
  to Apache users in protecting against certain instances of this problem.
  Please see the previous document for a description of what this patch does.
  As of the writing of this document, we have not yet released a new version
  of Apache that includes these patches.  We expect to do so in the near
  future, once we are more confident that we have addressed all the issues.
  
  <LI><A HREF="encoding_examples.html">Encoding Examples</A> page, describing
  how to properly encode your output to protect against this problem using
  common Apache related technologies, such as Apache modules, Perl, 
  and PHP.
  </UL>
  
  <H2>The Future</H2>
  
  <P>We do not expect this to be the last word on methods of exploiting
  this problem.  It is likely that there will be more changes to Apache in
  the future to help users deal with this issue, even if no more bugs are
  found in Apache itself.  Although we do provide most of the necessary
  information for sites to protect themselves against this type of attack,
  there are still many open issues associated with this issue.  
  
  <P>We realize that this is a complex issue and expect to update these 
  pages to describe the issues and fixes in more depth as time permits.
  
  <H2>Why the name "Cross Site Scripting"?</H2>
  
  <P>This issue isn't just about scripting, and there isn't necessarily 
  anything cross site about it.  So why the name?  It was coined earlier
  on when the problem was less understood, and it stuck.  Believe me, we
  have had more important things to do than think of a better name.
  &lt;g&gt;.
  
  <H2>Change History</H2>
  <UL>
  <LI>Wed Feb  2 01:06:01 MST 2000: initial revision.
  </UL>
  
  <H2>Thanks</H2>
  Thanks to <A HREF="http://www.cert.org/">CERT</A> for contacting the 
  Apache Software Foundation and not only allowing us to participate
  in the evaluation and release of this issue, but actively supporting
  our participation.  We would also like to thank <A
  HREF="http://www.microsoft.com/">Microsoft</A> for their research and
  cooperation in dealing with this issue.
  
  </BODY>
  </HTML>