Райтап на задачу «Просмотр файлов»

12 ноября 2026
Иллюстрация к задаче «Просмотр файлов»
Категория:

Web

Задача «Просмотр файлов»

LastTeamLead

Автор:

LastTeamLead

Первая кровь:
4500zenja
Сложность:
Easy
Дата публикации:
30.09.2025
Решений:
362
Рейтинг:
4.6/5
Ссылка:
Решать

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

Почему уязвимость работает

normpath() не делает путь абсолютным. Он просто «чистит» строку.

Проверка startswith() смотрит на строку. Она не проверяет, к какому файлу операционная система в итоге разрешит этот путь. Это уязвимость класса Path Traversal.

Как исправить уязвимость

Допустим, вам в голову пришло написать подобный сервис, но вы не хотите допустить, чтобы пользователь мог открыть закрытые файлы.

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

from pathlib import Path

from flask import Flask, abort, request, send_file

app = Flask(__name__)
PUBLIC_DIR = Path("/srv/public-documents").resolve(strict=True)


@app.get("/documents")
def read_document():
    name = request.args.get("name", "").strip()
    if not name or Path(name).is_absolute():
        abort(400)

    try:
        candidate = (PUBLIC_DIR / name).resolve()
    except (OSError, RuntimeError, ValueError):
        abort(400)

    if not candidate.is_relative_to(PUBLIC_DIR):
        abort(403)

    if not candidate.is_file():
        abort(404)

    return send_file(candidate)

Теперь мы используем библиотеку pathlib вместо os.

  1. Сначала отклоняем абсолютные пути. Оператор / у Path соединяет разрешённый каталог с относительным именем.
  2. resolve() превращает путь в абсолютный и разрешает символические ссылки. is_relative_to() затем проверяет, что итоговый путь остался внутри разрешённого каталога.
  3. Перед отправкой убеждаемся, что итоговый путь ведёт к обычному файлу.
Если вы нашли опечатку или ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter

Также по теме:

Райтап на задачу «Просмотр файлов»

/Разборы задач

Райтап на задачу «Просмотр файлов»

Райтап feadal на задачу «Просмотр файлов»: проверка пути через startswith, поведение os.path.normpath и обход запрета на чтение файла.
Прочитать

125

Райтап на задачу «Шакализатор картинок»

/Разборы задач

Райтап на задачу «Шакализатор картинок»

Разбор задачи «Шакализатор картинок»: Path Traversal, анализ nginx и PHP, обход проверки пути и чтение файла .env.
Прочитать

195