]> granicus.if.org Git - apache/commitdiff
Security rollup for 2.0.40 release. Tag and roll baby.
authorWilliam A. Rowe Jr <wrowe@apache.org>
Fri, 9 Aug 2002 17:00:44 +0000 (17:00 +0000)
committerWilliam A. Rowe Jr <wrowe@apache.org>
Fri, 9 Aug 2002 17:00:44 +0000 (17:00 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@96327 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
modules/mappers/mod_negotiation.c
server/util.c

diff --git a/CHANGES b/CHANGES
index 0992e9686a8167c10617d0e3ade8d9a1cac939bc..5ad91e9183f907210b5f7c012ca54017fc0c6122 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,29 @@
 Changes with Apache 2.0.40
 
+  *) SECURITY: [CAN-2002-0661] Close a very significant security hole that 
+     applies only to the Win32, OS2 and Netware platforms.  Unix was not 
+     affected, Cygwin may be affected.  Certain URIs will bypass security
+     and allow users to invoke or access any file depending on the system 
+     configuration.  Without upgrading, a single .conf change will close 
+     the vulnerability.  Add the following directive in the global server
+     httpd.conf context before any other Alias or Redirect directives;
+         RedirectMatch 400 "\\\.\."
+     Reported by Auriemma Luigi <bugtest@sitoverde.com>.
+     [Brad Nicholes]
+
+  *) SECURITY:  Close a path-revealing exposure in multiview type
+     map negotiation (such as the default error documents) where the
+     module would report the full path of the typemapped .var file when
+     multiple documents or no documents could be served based on the mime
+     negotiation.  Reported by Auriemma Luigi <bugtest@sitoverde.com>.
+     [CAN-2002-0654]  [William Rowe]
+
+  *) SECURITY:  Close a path-revealing exposure in cgi/cgid when we 
+     fail to invoke a script.  The modules would report "couldn't create 
+     child process /path-to-script/script.pl" revealing the full path
+     of the script.  Reported by Jim Race <jrace@qualys.com>.
+     [CAN-2002-0654]  [Bill Stoddard]
+
   *) Set aside the apr-iconv and apr_xlate() features for the Win32
      build of 2.0.40 so development can be completed.  A patch, from
      <http://www.apache.org/dist/httpd/patches/apply_to_2.0.40/>
index 61b30e51a11083467545ea94ecdff713c101f597..97189aa355b64df6cbd25a6d1d4f59815e6eaa7a 100644 (file)
@@ -984,7 +984,7 @@ static int read_type_map(apr_file_t **map, negotiation_state *neg, request_rec *
                      break;
                 }
                 mime_info.bytes = len;
-                mime_info.file_name = rr->filename;
+                mime_info.file_name = apr_filename_of_pathname(rr->filename);
             }
         }
         else {
@@ -1048,15 +1048,15 @@ static int read_types_multi(negotiation_state *neg)
 
     clean_var_rec(&mime_info);
 
-    if (!(filp = strrchr(r->filename, '/'))) {
-        return DECLINED;        /* Weird... */
+    if (r->proxyreq || !r->filename 
+                    || !ap_os_is_path_absolute(neg->pool, r->filename)) {
+        return DECLINED;
     }
 
-    /* XXX this should be more general, and quit using 'specials' */
-    if (strncmp(r->filename, "proxy:", 6) == 0) {
+    /* Only absolute paths here */
+    if (!(filp = strrchr(r->filename, '/'))) {
         return DECLINED;
     }
-
     ++filp;
     prefix_len = strlen(filp);
 
@@ -2685,8 +2685,15 @@ static int do_negotiation(request_rec *r, negotiation_state *neg,
              * non-neighboring variant.  We can have a non-neighboring
              * variant when processing a type map.  
              */
-            if (ap_strchr_c(variant->file_name, '/'))
+            if (ap_strchr(variant->file_name, '/'))
+                neg->is_transparent = 0;
+
+            /* We can't be transparent, because of the behavior
+             * of variant typemap bodies.  
+             */
+            if (variant->body) {
                 neg->is_transparent = 0;
+            }
         }
     }
 
@@ -2818,9 +2825,6 @@ static int handle_map_file(request_rec *r)
         apr_bucket *e;
 
         ap_allow_standard_methods(r, REPLACE_ALLOW, M_GET, M_OPTIONS, M_POST, -1);
-        if ((res = ap_discard_request_body(r)) != OK) {
-            return res;
-        }
         /*if (r->method_number == M_OPTIONS) {
          *    return ap_send_http_options(r);
          *}
@@ -2841,6 +2845,9 @@ static int handle_map_file(request_rec *r)
             return res;
         }
 
+        if ((res = ap_discard_request_body(r)) != OK) {
+            return res;
+        }
         bb = apr_brigade_create(r->pool, c->bucket_alloc);
         e = apr_bucket_file_create(map, best->body, 
                                    (apr_size_t)best->bytes, r->pool,
index c86e37cdbf0b4512886edd187cc11b9f30f9efa1..f0aabab11251987a897176be4b084b450421358d 100644 (file)
  */
 #define TEST_CHAR(c, f)        (test_char_table[(unsigned)(c)] & (f))
 
+/* Win32/NetWare/OS2 need to check for both forward and back slashes
+ * in ap_getparents() and ap_escape_url.
+ */
+#ifdef CASE_BLIND_FILESYSTEM
+#define IS_SLASH(s) ((s == '/') || (s == '\\'))
+#else
+#define IS_SLASH(s) (s == '/')
+#endif
+
+
 /*
  * Examine a field value (such as a media-/content-type) string and return
  * it sans any parameters; e.g., strip off any ';charset=foo' and the like.
@@ -485,7 +495,7 @@ AP_DECLARE(void) ap_getparents(char *name)
     }
     l = w = first_dot = next - name;
     while (name[l] != '\0') {
-       if (name[l] == '.' && name[l + 1] == '/' && (l == 0 || name[l - 1] == '/'))
+       if (name[l] == '.' && IS_SLASH(name[l + 1]) && (l == 0 || IS_SLASH(name[l - 1])))
            l += 2;
        else
            name[w++] = name[l++];
@@ -494,7 +504,7 @@ AP_DECLARE(void) ap_getparents(char *name)
     /* b) remove trailing . path, segment */
     if (w == 1 && name[0] == '.')
        w--;
-    else if (w > 1 && name[w - 1] == '.' && name[w - 2] == '/')
+    else if (w > 1 && name[w - 1] == '.' && IS_SLASH(name[w - 2]))
        w--;
     name[w] = '\0';
 
@@ -502,13 +512,13 @@ AP_DECLARE(void) ap_getparents(char *name)
     l = first_dot;
 
     while (name[l] != '\0') {
-       if (name[l] == '.' && name[l + 1] == '.' && name[l + 2] == '/' &&
-           (l == 0 || name[l - 1] == '/')) {
+       if (name[l] == '.' && name[l + 1] == '.' && IS_SLASH(name[l + 2]) &&
+           (l == 0 || IS_SLASH(name[l - 1]))) {
            register int m = l + 3, n;
 
            l = l - 2;
            if (l >= 0) {
-               while (l >= 0 && name[l] != '/')
+               while (l >= 0 && !IS_SLASH(name[l]))
                    l--;
                l++;
            }
@@ -525,10 +535,10 @@ AP_DECLARE(void) ap_getparents(char *name)
     /* d) remove trailing xx/.. segment. */
     if (l == 2 && name[0] == '.' && name[1] == '.')
        name[0] = '\0';
-    else if (l > 2 && name[l - 1] == '.' && name[l - 2] == '.' && name[l - 3] == '/') {
+    else if (l > 2 && name[l - 1] == '.' && name[l - 2] == '.' && IS_SLASH(name[l - 3])) {
        l = l - 4;
        if (l >= 0) {
-           while (l >= 0 && name[l] != '/')
+           while (l >= 0 && !IS_SLASH(name[l]))
                l--;
            l++;
        }
@@ -1547,7 +1557,7 @@ AP_DECLARE(int) ap_unescape_url(char *url)
            else {
                *x = x2c(y + 1);
                y += 2;
-               if (*x == '/' || *x == '\0')
+               if (IS_SLASH(*x) || *x == '\0')
                    badpath = 1;
            }
        }