Subject: Re: tar ignores filenames that contain `..'
To: Alistair Crooks <agc@wasabisystems.com>
From: Todd Vierling <tv@pobox.com>
List: tech-pkg
Date: 10/23/2002 15:21:13
On Wed, 23 Oct 2002, Todd Vierling wrote:

: Symbolic links whose *content* contains "../" are not the same thing as file
: entries in a tar file whose *filename* contains "../".
:
: The former should be unconditionally allowed by pax, as the default is to
: unlink before creating; there's no risk of overwriting files outside the
: destination tree, even if a created symlink points outside the destination
: tree.

I have been told offlist that there does exist one possibility where this
can be a bad thing, but ONLY IF some proper security checks aren't being
done ahead of time in pax.  As of pax in NetBSD 1.6, such checks are not
being done.

$ ln -s .. foo
$ touch foo/bar
$ pax -wf symlinktest.tar foo foo/bar

The resultant tarfile contains two entries:

lrwxr-xr-x  1 tv       staff          0 Oct 23 14:59 foo => ..
-rw-r--r--  1 tv       staff          0 Oct 23 14:59 foo/bar

Note the order of the entries, which is important.  Also note the lack of a
directory entry for "foo" preceding "foo/bar" (caused by explicitly adding
the file "foo/bar" rather than recursively adding a directory "foo").
Basically, this tar file is bad form, but only because it's already known
that "foo" (as a component of "foo/bar") is not a directory.

This, in itself, is not necessarily a security problem, as a sysadmin could
want to do this for legitimate purposes.  It can be a security problem when
blindly extracting some tarfiles.  However, it's NOT acceptable simply to
skip over symlinks containing "../", as that *will* defeat the common use of
tar/pax/cpio/etc. as a *backup tool*.

=====

The following refinements in pax (and *tools that use it*) would eliminate
these problems without sacrificing flexibility:

1. Create a "safe mode" flag in pax, which will make all of the following
   an error rather than a warning.  Use this flag in e.g. pkg_add(8).

2. Cache a list of symlinks encountered during extraction.  If a file is
   encountered which contains this symlink name at the start of its path
   followed by a "/" (i.e. a file that will follow that earlier symlink as
   if it were a directory), warn stderr about this, such as:

   "%s: pathname contains pre-created symbolic link %s"

3. If a file is encountered in the archive which contains "../" in its
   pathname, warn (without regard to whether the path appears to stay within
   the tarfile), such as:

   "%s: file %s contains parent directory entry; suggest using option -s"

4. Warn if a directory entry appears in the archive which corresponds to an
   symlink already existing in the filesystem.

=====

Note that I don't mention even issuing a warning if a *file* in a tarball
extracts across a symlink already existing in the filesystem.  That's a
quite useful feature that can be termed "pilot error" if it munges
something, and isn't pax's responsibility to check.  This is also the reason
that (2) above suggests caching a symlink list rather than doing
lstat(2)-walks.

-- 
-- Todd Vierling <tv@pobox.com>