﻿# V5628\. OWASP\. Possible Zip Slip vulnerability\. Potentially tainted data is used in the path to extract the file\.

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

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

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

Рассмотрим пример небезопасного кода:

```cpp
public void ExtractArchive(ZipArchive archive, string destinationDirectory)
{
  var entries = archive.Entries;
  foreach (var entry in entries)
  {
    var extractPath = Path.Combine(destinationDirectory, entry.FullName);
    entry.ExtractToFile(extractPath, true);
  }
}
```

Здесь внутри цикла файлы поочередно извлекаются из архива в директорию, расположенную по пути 'destinationDirectory'\. Для каждого файла создаётся путь распаковки с помощью метода 'Path\.Combine', после чего результат записывается в переменную 'extractPath'\. Далее 'extractPath' используется в качестве аргумента метода 'entry\.ExtractToFile', выполняющего разархивирование файла по заданному пути\.

Предположим, что архив должен быть извлечён в директорию 'C:\\ApplicationFiles\\UserFiles'\. Однако если свойство 'entry\.FullName' вернёт строку вида '\\\.\.\\config\.ini', файл попадёт в корневой каталог приложения 'C:\\ApplicationFiles'\. В случае совпадения имени извлекаемого файла и, например, файла конфигурации приложения, будет выполнена перезапись последнего\.

Обезопасить код в предыдущем примере можно, например, следующим образом:

```cpp
public void ExtractArchive(ZipArchive archive, string destinationDirectory)
{
  var destinationDirectoryFullPath = Path.GetFullPath(destinationDirectory);
  foreach (var entry in archive.Entries)
  {
    var extractPath = Path.Combine(destinationDirectory, entry.FullName);
    var extractFullPath = Path.GetFullPath(extractPath);
    if (!extractFullPath.StartsWith(destinationDirectoryFullPath))
    {
      throw new IOException("Zip Slip vulnerability");
    }

    entry.ExtractToFile(extractFullPath);
  }
}
```

Здесь в переменную 'extractFullPath' записывается результат обработки пути 'extractPath' методом 'Path\.GetFullPath'\. В ходе этой операции путь, содержащий "dot\-dot\-slash" последовательности, будет заменен на аналогичный, не включающий их\. 

После этого с помощью метода 'extractFullPath\.StartsWith' проверяется, не изменилась ли директория для распаковки файла в результате предыдущей операции\. В случае если произошла подмена директории, выбрасывается исключение\.