mirror of
https://github.com/mirror/wget.git
synced 2025-03-28 21:10:20 +08: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:
parent
27483fd0f5
commit
0410411939
@ -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>
|
2002-08-03 Hrvoje Niksic <hniksic@xemacs.org>
|
||||||
|
|
||||||
* init.c (cmd_file): Allocate RESULT correctly.
|
* init.c (cmd_file): Allocate RESULT correctly.
|
||||||
|
@ -35,6 +35,11 @@ so, delete this exception statement from your version. */
|
|||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "wget.h"
|
#include "wget.h"
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
# include <string.h>
|
||||||
|
#else
|
||||||
|
# include <strings.h>
|
||||||
|
#endif /* HAVE_STRING_H */
|
||||||
#include "fnmatch.h"
|
#include "fnmatch.h"
|
||||||
|
|
||||||
/* Match STRING against the filename pattern PATTERN, returning zero
|
/* 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 (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
|
/* Return non-zero if S contains globbing wildcards (`*', `?', `[' or
|
||||||
`]'). */
|
`]'). */
|
||||||
int
|
int
|
||||||
|
@ -40,6 +40,7 @@ so, delete this exception statement from your version. */
|
|||||||
#define FNM_NOMATCH 1
|
#define FNM_NOMATCH 1
|
||||||
|
|
||||||
int fnmatch PARAMS ((const char *, const char *, int));
|
int fnmatch PARAMS ((const char *, const char *, int));
|
||||||
|
int has_insecure_name_p PARAMS ((const char *s));
|
||||||
int has_wildcards_p PARAMS ((const char *));
|
int has_wildcards_p PARAMS ((const char *));
|
||||||
|
|
||||||
#endif /* FNMATCH_H */
|
#endif /* FNMATCH_H */
|
||||||
|
19
src/ftp.c
19
src/ftp.c
@ -1593,7 +1593,7 @@ Not descending to `%s' as it is excluded/not-included.\n"), newdir);
|
|||||||
static uerr_t
|
static uerr_t
|
||||||
ftp_retrieve_glob (struct url *u, ccon *con, int action)
|
ftp_retrieve_glob (struct url *u, ccon *con, int action)
|
||||||
{
|
{
|
||||||
struct fileinfo *orig, *start;
|
struct fileinfo *f, *orig, *start;
|
||||||
uerr_t res;
|
uerr_t res;
|
||||||
|
|
||||||
con->cmd |= LEAVE_PENDING;
|
con->cmd |= LEAVE_PENDING;
|
||||||
@ -1606,8 +1606,7 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action)
|
|||||||
opt.accepts and opt.rejects. */
|
opt.accepts and opt.rejects. */
|
||||||
if (opt.accepts || opt.rejects)
|
if (opt.accepts || opt.rejects)
|
||||||
{
|
{
|
||||||
struct fileinfo *f = orig;
|
f = orig;
|
||||||
|
|
||||||
while (f)
|
while (f)
|
||||||
{
|
{
|
||||||
if (f->type != FT_DIRECTORY && !acceptable (f->name))
|
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;
|
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.
|
/* Now weed out the files that do not match our globbing pattern.
|
||||||
If we are dealing with a globbing pattern, that is. */
|
If we are dealing with a globbing pattern, that is. */
|
||||||
if (*u->file && (action == GLOBALL || action == GETONE))
|
if (*u->file && (action == GLOBALL || action == GETONE))
|
||||||
{
|
{
|
||||||
int matchres = 0;
|
int matchres = 0;
|
||||||
struct fileinfo *f = start;
|
|
||||||
|
|
||||||
|
f = start;
|
||||||
while (f)
|
while (f)
|
||||||
{
|
{
|
||||||
matchres = fnmatch (u->file, f->name, 0);
|
matchres = fnmatch (u->file, f->name, 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user