# V5609. OWASP. Possible path traversal vulnerability. Potentially tainted data is used as a path.

Анализатор обнаружил, что данные, полученные из внешнего источника, используются в качестве путей к файлам или папкам без предварительной проверки. Это может стать причиной уязвимости приложения к атакам path traversal.

Атаки этого типа выделены в отдельную категорию рисков в OWASP Top 10 Application Security Risks 2017: A5:2017-Broken Access Control.

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

    HttpResponse response;
    HttpRequest request;

    private void SendUserFileContent(string userDirectory)
    {
      ....
      string userFileRelativePath = request.QueryString["relativePath"];
      string fullPath = Path.Combine(userDirectory,
                                     userFileRelativePath);
      var content = File.ReadAllText(fullPath);

      ....

      response.Write(content);
    }

Данный метод производит отправку содержимого некоторого файла из заданной папки пользователя. Предполагается, что пользователь должен иметь возможность получения содержимого только файлов, хранящихся внутри этой папки.

В качестве относительного пути здесь используется значение, полученное из внешнего источника – 'Request.QueryString'. Отсутствие каких-либо проверок позволяет злоумышленнику получить доступ к содержимому любых файлов в системе.

Например, в папке каждого пользователя может храниться файл userInfo.xml, в котором содержится различная (в том числе конфиденциальная) информация (при этом код выполняется на системе Windows). Тогда для получения доступа к данным пользователя 'admin' злоумышленник может передать в 'Request. QueryString["relativePath"]' следующую строку:

    ..\admin\userInfo.xml

Для защиты от такой атаки недостаточно простой проверки на наличие '..\' в начале строки. К примеру, для получения тех же данных может передаваться и строка

    someFolder\..\..\admin\userInfo.xml

Ещё одна возможность для атаки – передача абсолютного пути вместо относительного. Если один из аргументов 'Path.Combine' представляет собой абсолютный путь, то все ранее записанные аргументы игнорируются. К примеру, метод может быть вызван следующим образом:

    Path.Combine("folder", "childFolder", "C:\Users\Admin\secret.txt")

В результате будет возвращена строка 'C:\Users\Admin\secret.txt '. Таким образом, отсутствие проверки входных данных позволяет злоумышленнику получить доступ к любому файлу в системе. Более подробно атаки типа path traversal и способы их проведения описаны на официальном сайте OWASP по ссылке.

Для обеспечения защиты от path traversal необходимо применять различные средства проверки входных данных. В примере, описанном выше, можно использовать проверку на наличие подстрок ":" и "..\":

    HttpResponse response;
    HttpRequest request;

    private void SendUserFileContent(string userDirectory)
    {
      ....
      string userFileRelativePath = request.QueryString["relativePath"];

      if (   !userFileRelativePath.Contains(":")
          && !userFileRelativePath.Contains(@"..\"))
      {
        string fullPath = Path.Combine(userDirectory,
                                       userFileRelativePath);
        var content = File.ReadAllText(fullPath);

        ....

        response.Write(content);
      }
      else
      {
        ....
      }
    }

Анализатор также считает источниками небезопасных данных параметры методов, доступных из других сборок. Эта тема подробно раскрыта в заметке "Почему важно проверять значения параметров общедоступных методов".

Рассмотрим пример кода, выполняющегося на ОС Windows:

    public class UserFilesManager
    {
      private const string UsersDirectoryAbsolutePath = ....;
      private HttpResponse response;
      private string userName;

      public void WriteUserFile(string relativePath)
      {
        string path = Path.Combine(UsersDirectoryAbsolutePath,
                                   userName,
                                   relativePath);
        WriteFile(path);
      }

      private void WriteFile(string absolutePath)
      {
        response.Write(File.ReadAllText(absolutePath));
      }
    }

Анализатор сформирует предупреждение низкого уровня достоверности на вызов метода 'WriteFile' внутри 'WriteUserFile'. После вызова 'Path.Combine' небезопасные данные из 'relativePath' передаются в 'path', после чего выступают в качестве аргумента вызова 'WriteFile', где используются в качестве пути. Таким образом, пользовательский ввод может попасть в метод 'File.ReadAllText' без проверки, из-за чего данный код уязвим к path traversal.

Для защиты от атаки необходимо проводить валидацию параметров. В данном случае важно провести её до вызова 'Path.Combine', так как возвращаемое им значение в любом случае будет абсолютным путём:

    public void WriteUserFile(string relativePath)
    {
      if (relativePath.Contains(":") || relativePath.Contains(@"..\"))
      {
        ....

        return;
      }

      string path = Path.Combine(UsersDirectoryAbsolutePath,
                                 userName,
                                 relativePath);
      WriteFile(path);
    }

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

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

CWE-22 OWASP-12.3.1

Взгляните на примеры ошибок, обнаруженных с помощью диагностики V5609.