Directory Traversal

1. Введение:

Обход каталога (также известный как обход пути к файлу) - это уязвимость веб-безопасности, которая позволяет злоумышленнику читать произвольные файлы на сервере, где запущено приложение. Это может быть код и данные приложения, учетные данные для внутренних систем и важные файлы операционной системы. В некоторых случаях злоумышленник может записывать данные в произвольные файлы на сервере, что позволяет ему изменять данные или поведение приложения и, в конечном итоге, получить полный контроль над сервером.

2. Типичный уязвимый код:

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

private static final String BASE_PATH = "/storage/items/images";

private void getProfileImage(HttpServletRequest request, 
HttpServletResponse response) throws IOException {
    
    String folderName = request.getParameter("folder");
    String fileName = request.getParameter("file");
    String path = BASE_PATH + folderName + fileName;

    File file = new File(path);
    
    buildResponse(response, file);
}

private void constructResponse(HttpServletResponse response, 
File file) throws IOException {
    
    response.setContentType("image/png");
    
    OutputStream os = response.getOutputStream();
    
    // Notice there is no extra validation on the path of the file, it is read 
    // straight away.
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
   
    byte[] buffer =  new byte[1024];
    int read;

    while ((read = bis.read(buffer)) != -1) {
        os.write(buffer, 0, read);
    }

    bis.close();
    os.flush();
    os.close();
}

Мы считываем тот факт, что путь строится (на основе BASE_PATH и полученного запроса на имя файла и папки).

Догадываясь об этом, злоумышленник может ввести в имя файла вредоносный путь, например ../../../etc/passwd, который преобразуется в /storage/items/images/../../../etc/passwd (предполагается, что мы имеем дело с UNIX-системой), который затем интерпретируется системой как /etc/passwd, что приводит к утечке файла passwd.

3. Смягчение последствий:

3.1. Проверка абсолютного пути:

Самый эффективный способ предотвратить уязвимости Directory Traversal - не передавать пользовательский ввод в API файловой системы. Многие функции приложений, которые это делают, можно переписать, чтобы обеспечить более безопасное поведение.

Однако если это невозможно, приложение должно выполнять строгую проверку ввода параметров, предназначенных для операций с файловой системой. К ним относятся проверка пути и проверка абсолютного пути к данным, предоставленным пользователем.

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

private static final String BASE_PATH = "/storage/items/images";

private void getProfileImage(HttpServletRequest request, 
 HttpServletResponse response) throws IOException {
    
    String folderName = request.getParameter("folder");
    String fileName = request.getParameter("file");
    String path = BASE_PATH + folderName + fileName;

    File file = new File(path);
    
    String canonicalPath = file.getCanonicalPath();

    // Check whether the given path corresponds to the base path
    //(where the image files are stored)
    if(canonicalPath.startsWith(BASE_PATH)) {
        buildResponse(response, file);
    } else {
        throw new GenericException("Access denied.");
    }
}

private void constructResponse(HttpServletResponse response,
 File file) throws IOException {
    
    response.setContentType("image/png");
    
    OutputStream os = response.getOutputStream();
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
   
    byte[] buffer =  new byte[1024];
    int read;

    while ((read = bis.read(buffer)) != -1) {
        os.write(buffer, 0, read);
    }

    bis.close();
    os.flush();
    os.close();
}

3.2. Использование службы хостинга файлов:

Подобный подход к безопасному хранению файлов на CDN/облачном сервисе мы уже обсуждали здесь:

File Upload

Кроме того, извлечение этих файлов по умолчанию будет осуществляться безопасным и эффективным способом. Они очень просты в применении и использовании, так что вам определенно стоит использовать их в дальнейшем.

3.3. Косвенные ссылки на файлы:

Если хранение файлов на локальном сервере действительно необходимо, то наиболее безопасным способом защиты от атак обхода каталога является косвенный: вы присваиваете каждому файлу произвольный идентификатор, соответствующий пути к файлу, а затем заставляете все URL ссылаться на файл по этому идентификатору. Это можно сделать, например, с помощью базы данных (где хранится ссылка между путем к файлу и его относительным идентификатором)

4. Выводы:

Проверка абсолютного пути представляет собой основу защиты от обхода каталога. Однако основным способом защиты является использование CDN или любых других систем хранения файлов в онлайне/облаке. Если хранение файлов на локальном сервере является одним из ваших требований, помните, что косвенные ссылки на файлы - это очень мощная техника, и вы должны ее использовать.

Last updated