# V5338. OWASP. Possible Zip Slip vulnerability. Potentially tainted data might be used to extract the file.

Анализатор обнаружил, что имя файла, полученное из архива, используется в качестве пути к файлам или папкам без предварительной проверки. Если в имени файла присутствуют "dot-dot-slash" последовательности, операции с файлом приведут к возникновению уязвимости Zip Slip в приложении.

Атаки этого типа выделены в отдельные категории рисков в OWASP Top 10 Application Security Risks:

- A01:2021 – Broken Access Control

Zip Slip осуществляется через передачу в приложение архива с вредоносными файлами внутри: они содержат в имени "dot-dot-slash" последовательности (`../../evil.csx`). Спровоцировав распаковку такого архива, злоумышленник может переписать любые файлы, к которым у приложения есть доступ.

В большинстве архиваторов и операционных систем создать файл с названием вида `../../evil.csx` не получится из-за встроенных ограничений, тем не менее, существуют инструменты, допускающие эту операцию. Из-за этого атака Zip Slip и становится возможной.

Рассмотрим пример:

    public void extractArchive(String destinationDir, ZipFile zip) {
        Enumeration<? extends ZipEntry> entries = zip.entries();
        while (entries.hasMoreElements()) {
            ZipEntry entry = entries.nextElement();

            File file = new File(destinationDir, entry.getName());

            InputStream input = zip.getInputStream(entry);
            IOUtils.copy(input, new WriterOutputStream(new FileWriter(file)));
        }
    }

Данный метод принимает архив и распаковывает его в `destinationDir`. Но путь до места распаковки файла создаётся из имени записи в архиве, из-за чего данный код подвержен уязвимости Zip Slip. Если в приложение попадёт вредоносный архив, то он может быть распакован в любом месте системы, к которому приложение имеет доступ.

Для защиты от Zip Slip можно проверять, находится ли целевой путь внутри исходной директории. В примере выше рекомендуется использовать метод `getCanonicalPath()` для приведения пути к канонической форме (путь без относительных переходов `..`, `.` и избыточных разделителей) с последующей проверкой через `startsWith(destinationDir)`. Это предотвратит доступ к файлам за пределами разрешённой директории, даже если путь содержит замаскированные относительные переходы, например, `../../evil.csx`.

Ожидается, что процесс распаковки любого архива будет защищён. Диагностическое правило считает все архивы внешними сущностями и потенциально подозрительными.

Исправленный пример:

    public void extractArchive(String destinationDir, ZipFile zip) {
        Enumeration<? extends ZipEntry> entries = zip.entries();
        while (entries.hasMoreElements()) {
            ZipEntry entry = entries.nextElement();

            File file = new File(destinationDir, entry.getName());

            if (file.getCanonicalPath().startsWith(destinationDir)) {
                InputStream input = zip.getInputStream(entry);
                IOUtils.copy(input, new WriterOutputStream(new FileWriter(file)));
            }
        }
    }

Выявляемые диагностикой ошибки классифицируются согласно ГОСТ Р 71207–2024 как критические и относятся к типу: Ошибки непроверенного использования чувствительных данных (ввода пользователя, файлов, сети и пр.).

Данная диагностика классифицируется как:

CWE-22 CWE-23 CWE-641 CWE-99 OWASP-5.1.4