]> sjero.net Git - wget/commitdiff
[svn] Fix for FTP directory traversal vulnerability (at least for Unix).
authorabbotti <devnull@localhost>
Sat, 11 Jan 2003 20:12:35 +0000 (12:12 -0800)
committerabbotti <devnull@localhost>
Sat, 11 Jan 2003 20:12:35 +0000 (12:12 -0800)
Based on a patch by Red Hat.
Published in <85u02vg4hukbc2fltdd51uds5oq14rd92f@farscape.privy.mev.co.uk>.

src/ChangeLog
src/fnmatch.c
src/fnmatch.h
src/ftp.c

index 13436c668daebecad796802d4c64709cad309be3..4dcc6d62014aace36d421b1a70671f1233d54958 100644 (file)
@@ -1,3 +1,15 @@
+2003-01-11  Ian Abbott <abbotti@mev.co.uk>
+
+       * ftp.c (ftp_retrieve_glob): Reject insecure filenames as determined
+       by calling new function has_insecure_name_p.  This is based on a
+       patch by Red Hat.
+
+       * fnmatch.c (has_insecure_name_p): New function: returns non-zero
+       if filename starts with `/' or contains `../' and is therefore
+       considered insecure.
+
+       * fnmatch.h: Declare has_insecure_name_p().
+
 2002-08-03  Hrvoje Niksic  <hniksic@xemacs.org>
 
        * init.c (cmd_file): Allocate RESULT correctly.
index 6689a1befa921a220c526431cf9cfb6871a9a771..39bf6e012ae1a90560def7805d348ea6c852e301 100644 (file)
@@ -35,6 +35,11 @@ so, delete this exception statement from your version.  */
 
 #include <errno.h>
 #include "wget.h"
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# include <strings.h>
+#endif /* HAVE_STRING_H */
 #include "fnmatch.h"
 
 /* Match STRING against the filename pattern PATTERN, returning zero
@@ -198,6 +203,19 @@ fnmatch (const char *pattern, const char *string, int flags)
   return (FNM_NOMATCH);
 }
 
+/* Return non-zero if S has a leading '/'  or contains '../' */
+int
+has_insecure_name_p (const char *s)
+{
+  if (*s == '/')
+    return 1;
+
+  if (strstr(s, "../") != 0)
+    return 1;
+
+  return 0;
+}
+
 /* Return non-zero if S contains globbing wildcards (`*', `?', `[' or
    `]').  */
 int
index d134672e40626138b04ba03781eabdda0aa7dcac..a3449aaa957da1574651bafad90e83a16b33bef5 100644 (file)
@@ -40,6 +40,7 @@ so, delete this exception statement from your version.  */
 #define        FNM_NOMATCH     1
 
 int fnmatch PARAMS ((const char *, const char *, int));
+int has_insecure_name_p PARAMS ((const char *s));
 int has_wildcards_p PARAMS ((const char *));
 
 #endif /* FNMATCH_H */
index 2ffd1c176359cbeec1e8d763000085fcda898685..c49f25e97859dcac3a72a344a5d211463713f4c7 100644 (file)
--- a/src/ftp.c
+++ b/src/ftp.c
@@ -1593,7 +1593,7 @@ Not descending to `%s' as it is excluded/not-included.\n"), newdir);
 static uerr_t
 ftp_retrieve_glob (struct url *u, ccon *con, int action)
 {
-  struct fileinfo *orig, *start;
+  struct fileinfo *f, *orig, *start;
   uerr_t res;
 
   con->cmd |= LEAVE_PENDING;
@@ -1606,8 +1606,7 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action)
      opt.accepts and opt.rejects.  */
   if (opt.accepts || opt.rejects)
     {
-      struct fileinfo *f = orig;
-
+      f = orig;
       while (f)
        {
          if (f->type != FT_DIRECTORY && !acceptable (f->name))
@@ -1619,13 +1618,25 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action)
            f = f->next;
        }
     }
+  /* Remove all files with possible harmful names */
+  f = orig;
+  while (f)
+    {
+      if (has_insecure_name_p(f->name))
+       {
+         logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"), f->name);
+         f = delelement (f, &start);
+       }
+      else
+       f = f->next;
+    }
   /* Now weed out the files that do not match our globbing pattern.
      If we are dealing with a globbing pattern, that is.  */
   if (*u->file && (action == GLOBALL || action == GETONE))
     {
       int matchres = 0;
-      struct fileinfo *f = start;
 
+      f = start;
       while (f)
        {
          matchres = fnmatch (u->file, f->name, 0);