marc        98/11/08 23:03:20

  Modified:    src      CHANGES
               src/modules/standard mod_include.c
  Log:
  Add more extensive checks to mod_include to avoid infinite recursive
  includes.
  
  The logic used is commented in the source.  It should be complete
  for the current Apache code base, but if something else starts modifying
  r->filename outside of a filename translation stage that could change.
  
  The code scans, at each stage, every subrequest for each level of
  an internal redirect so it ends up being O(n^2) total in the
  number of subrequests and internal redirects, but that shouldn't
  be an issue.
  
  PR: 3323
  
  Revision  Changes    Path
  1.1142    +3 -0      apache-1.3/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v
  retrieving revision 1.1141
  retrieving revision 1.1142
  diff -u -r1.1141 -r1.1142
  --- CHANGES   1998/11/08 21:24:03     1.1141
  +++ CHANGES   1998/11/09 07:03:16     1.1142
  @@ -1,5 +1,8 @@
   Changes with Apache 1.3.4
   
  +  *) SECURITY: Do a more complete check in mod_include to avoid 
  +     an infinite loop of recursive SSI includes.  [Marc Slemko] PR#3323
  +
     *) Add APACI --suexec-docroot and --suexec-logfile options which can be
        used to set the document root directory (DOC_ROOT) and the suexec
        logfile (LOG_EXEC), respectively. Additionally the --layout option
  
  
  
  1.106     +33 -5     apache-1.3/src/modules/standard/mod_include.c
  
  Index: mod_include.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/modules/standard/mod_include.c,v
  retrieving revision 1.105
  retrieving revision 1.106
  diff -u -r1.105 -r1.106
  --- mod_include.c     1998/09/24 14:06:42     1.105
  +++ mod_include.c     1998/11/09 07:03:19     1.106
  @@ -688,13 +688,41 @@
                       "in parsed file %s";
               }
               if (error_fmt == NULL) {
  +             /* try to avoid recursive includes.  We do this by walking
  +              * up the r->main list of subrequests, and at each level
  +              * walking back through any internal redirects.  At each
  +              * step, we compare the filenames and the URIs.  
  +              *
  +              * The filename comparison catches a recursive include
  +              * with an ever-changing URL, eg.
  +              * <!--#include virtual=
  +              *      "$REQUEST_URI/$QUERY_STRING?$QUERY_STRING/x"-->
  +              * which, although they would eventually be caught because
  +              * we have a limit on the length of files, etc., can 
  +              * recurse for a while.
  +              *
  +              * The URI comparison catches the case where the filename
  +              * is changed while processing the request, so the 
  +              * current name is never the same as any previous one.
  +              * This can happen with "DocumentRoot /foo" when you
  +              * request "/" on the server and it includes "/".
  +              * This only applies to modules such as mod_dir that 
  +              * (somewhat improperly) mess with r->filename outside 
  +              * of a filename translation phase.
  +              */
  +             int founddupe = 0;
                   request_rec *p;
  +                for (p = r; p != NULL && !founddupe; p = p->main) {
  +                 request_rec *q;
  +                 for (q = p; q != NULL; q = q->prev) {
  +                     if ( (strcmp(q->filename, rr->filename) == 0) ||
  +                          (strcmp(q->uri, rr->uri) == 0) ){
  +                         founddupe = 1;
  +                         break;
  +                     }
  +                 }
  +             }
   
  -                for (p = r; p != NULL; p = p->main) {
  -                    if (strcmp(p->filename, rr->filename) == 0) {
  -                        break;
  -                    }
  -                }
                   if (p != NULL) {
                       error_fmt = "Recursive include of \"%s\" "
                           "in parsed file %s";
  
  
  

Reply via email to