Subject: Re: ftp(1) security hole, and suggested fixes
To: None <tech-security@NetBSD.ORG>
From: der Mouse <mouse@Rodents.Montreal.QC.CA>
List: tech-security
Date: 08/17/1997 16:04:41
>> it is possible to trick the client into executing arbitrary code on
>> the client's machine by returning a filename such as '|sh', whose
>> contents are the list of shell commands to execute.

>> Suggested fix:
>> modify recvrequest() to take an extra argument, which means "ignore
>> special names such as '-' and '|*'".  use this flag when calling
>> recvrequest() from mget().  I've done this, and it appears to work.

> On second thought I don't think this is ideal: you also, if possible,
> want to protect against someone seeing a file called '|sh' on an ftp
> server and trying to get it.  If you do "get |sh", at present, the
> contents of the file on the server will be piped to sh since get
> copies its argv[1] to argv[2] if the user doesn't supply one.

So, you need to make sure that if argv[2] comes from _anywhere_ other
than the user explicitly supplying it to a get command (eg, an mget, or
via the automatic copy from argv[1] on a get), special characters like
| get ignored.

> So I propose instead prepending "./" to any automatically generated
> local name, both in get and mget, that begins with '|' or is '-'.

That would also work.

> Also, names beginning with '/' should have a '.' prepended to them --
> otherwise the server can send "/root/.rhosts" or
> "/home/victim/.rhosts" or whatever.

I think this should be true only when the path is returned from a
remote list operation, and possibly not even then.  I do things like
"get /tmp/transfer.tar.gz" often enough; indeed, while setting up
systems I have been known to do things akin to "mget /root/*".

> Additionally, everything that mget generates should have ".." path
> elements filtered out.

I don't like this because, as you point out, it breaks "mget ../*.c",
and (much more plausibly) "mget ../ksrc/ksrc*".

Ideally, what I'd like here is a three-way switch that controls what to
do with "dubious" pathnames, such as those beginning with / or
containing .. components: it could be set to "error out" (refuse to get
the file), "accept" (trust it), or "prompt" (ask the user).  And at the
prompt, the user should be able to switch it into either of the other
modes either for the remainder of the current operation or as if from
the ftp> prompt.

Not that I really expect to get that, unless I find time to implement
it myself.  Coming up with fixes is easy for people who don't have to
implement them. :-)

					der Mouse

			       mouse@rodents.montreal.qc.ca
		     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B