1
0
mirror of https://github.com/moparisthebest/wget synced 2024-07-03 16:38:41 -04:00

[svn] Fix for FTP directory traversal vulnerability (at least for Unix).

Based on a patch by Red Hat.
Published in <85u02vg4hukbc2fltdd51uds5oq14rd92f@farscape.privy.mev.co.uk>.
This commit is contained in:
abbotti 2003-01-11 12:12:35 -08:00
parent 27483fd0f5
commit 0410411939
4 changed files with 46 additions and 4 deletions

View 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.

View 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

View 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 */

View File

@ -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);