Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
Инструменты/GitHubGitHub/a1ohadance/cve-2026-38361
Vulnerability AnalysisExploitationWeb SecurityPenetration TestingLearning & Education
GitHuba1ohadance/cve-2026-38361

CVE-2026-38361

Advisory: CVE-2026-38361 multiple DoS vulnerabilities (CWE-400/CWE-670) in dash-uploader (Python/PyPI)

Репозиторий
3 месяцев назадЕщё не проверено

Популярное

Смотреть все →

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

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

CVE-2026-38361: Множественные уязвимости типа «Отказ в обслуживании» (DoS) без аутентификации в dash-uploader

CVE NVD CWE-400 CWE-670 Severity Patch Auth Version PyPI Downloads Total Downloads License

Множественные проблемы «Отказа в обслуживании» (DoS) без аутентификации в fohrloop/dash-uploader (Python, PyPI), включая (но не ограничиваясь) крах процесса из-за нехватки памяти (OOM), усечение файла до нулевого размера, постоянное исчерпание дискового пространства и полный обход документированного ограничения max_file_size. Дополнительные пути злоупотребления ресурсами существуют через тот же несанированный набор параметров.

⚠️ Патч недоступен и никогда не будет выпущен

Репозиторий был заархивирован 2025-07-19 без активного мейнтейнера. Все опубликованные версии (от 0.1.0 до 0.7.0a2) затронуты и останутся таковыми. Пакет всё ещё набирает примерно 28 000 загрузок в месяц.

Любой, кто использует dash-uploader в продакшене, должен применить собственные меры смягчения. Рекомендуемое исправление — перейти на встроенный компонент dcc.Upload из Plotly Dash. Полные варианты см. в разделе Смягчение.

Описание

HTTP-обработчик dash-uploader принимает неаутентифицированные POST-запросы с параметрами, контролируемыми атакующим, которые затем используются при выделении памяти, файловых операциях и создании каталогов без проверки границ, ограничения скорости или механизма очистки. Четыре независимые проблемы в одном и том же участке кода:

1. Крах из-за нехватки памяти (OOM) (подтверждено)

Подтверждено на системе с 7,7 ГБ: 5 одновременных POST-запросов с resumableTotalChunks=30000000 вызвали OOM-killer за 2 секунды. Лог ядра подтверждает:

root@kitploit:~
Out of memory: Killed process 24203 (python3) total-vm:8302276kB, anon-rss:7068012kB

Каждый запрос выделяет примерно 2.9 ГБ через списковое включение по range(1, resumableTotalChunks + 1). Серверный процесс завершается, и приложение становится полностью недоступным до ручного перезапуска.

2. Усечение файла (подтверждено)

Файл размером 42 байта был уменьшен до 0 байт с помощью одного POST-запроса с resumableTotalChunks=0. Основная причина — all() в Python возвращает True для пустых итераций, что обманывает обработчик загрузки, заставляя его считать нулевое количество частей завершённой загрузкой. Существующий файл удаляется через os.unlink() и заменяется пустым файлом.

3. Накопление заброшенных загрузок (подтверждено)

10 потерянных временных каталогов с файлами частей было создано и сохранялось на диске бессрочно. Поиск по всем исходным файлам на предмет cleanup, ttl, expire, garbage, purge, cron, schedule и periodic не дал результатов. Единственный вызов очистки (shutil.rmtree) выполняется исключительно при завершённых загрузках. Механизма освобождения дискового пространства от незавершённых сессий нет.

4. Обход max_file_size (подтверждено)

Сервер принял часть размером 5 МБ для файла с заявленным resumableTotalSize=999999999999 (~999 ГБ) с HTTP 200. Параметр max_file_size передаётся только компоненту React на JavaScript. Сервер никогда не проверяет размер файла, размер части, Content-Length или Flask MAX_CONTENT_LENGTH. Разработчик, установивший max_file_size=10, не получает никакой защиты на стороне сервера.

Уязвимый код

root@kitploit:~
# dash_uploader/httprequesthandler.py
def _post(self):
    resumableTotalChunks = request.form.get("resumableTotalChunks", type=int)   # attacker-controlled, no bounds
    ...
    chunk_paths = [
        os.path.join(temp_dir, get_chunk_name(resumableFilename, x))
        for x in range(1, resumableTotalChunks + 1)                              # unbounded; e.g. 30M -> ~2.9 GB -> OOM
    ]
    upload_complete = all([os.path.exists(p) for p in chunk_paths])              # all([]) is True -> truncation when chunks=0
    if upload_complete:
        target_file_name = os.path.join(temp_root, resumableFilename)
        if os.path.exists(target_file_name):
            os.unlink(target_file_name)                                          # existing file deleted
        with open(target_file_name, "ab") as target_file:
            for p in chunk_paths:                                                # empty list -> empty file written
                ...

Один и тот же участок кода порождает как OOM (большое значение resumableTotalChunks), так и примитив усечения файла (resumableTotalChunks=0).

Векторы атаки

Атакующий отправляет неаутентифицированные POST-запросы на конечную точку /API/resumable.

  • Крах OOM: 5 одновременных запросов с resumableTotalChunks=30000000 выделяют ~2.9 ГБ каждый, вызывая OOM-killer.
  • Исчерпание диска: начать загрузку, но никогда не завершать её; потерянные временные файлы накапливаются навсегда.
  • Усечение файла: отправить resumableTotalChunks=0; Python all([])=True заставляет сервер перезаписать целевой файл пустым содержимым.
  • Обход размера: любое ограничение размера, установленное разработчиком, применяется только в клиентском JavaScript, поэтому прямой HTTP-запрос полностью его обходит.

Аутентификация или привилегии не требуются.

Влияние

  • Крах серверного процесса через OOM-killer, вызванный неограниченным выделением памяти из одного контролируемого пользователем POST-параметра (resumableTotalChunks)
  • Постоянное исчерпание диска из-за заброшенных сессий загрузки, которые никогда не очищаются (в коде нет TTL, сборки мусора или механизма истечения срока)
  • Исчерпание индексных дескрипторов файловой системы через создание каталогов произвольной глубины с помощью os.makedirs() с несанированным resumableIdentifier
  • Уничтожение данных через усечение файла до нулевого размера, вызванное тем, что Python all() возвращает True для пустых итераторов при resumableTotalChunks=0
  • Обход всех ограничений размера файла, поскольку max_file_size применяется только в клиентском JavaScript, а серверный обработчик не выполняет никакой проверки размера и никогда не устанавливает Flask MAX_CONTENT_LENGTH

Затронутые компоненты

  • dash_uploader/httprequesthandler.py (метод BaseHttpRequestHandler._post)
  • dash_uploader/upload.py (функция Upload, параметр max_file_size)
  • dash_uploader/configure_upload.py (отсутствует MAX_CONTENT_LENGTH)

Смягчение

⚠️ Патч недоступен, а проект заархивирован

Варианты для тех, кто уже использует пакет, в порядке предпочтения:

  1. Перейти на dcc.Upload — официальный компонент загрузки, поставляемый с Plotly Dash. У него нет параметра количества частей, нет временного состояния на диске, и он уважает Flask MAX_CONTENT_LENGTH. Ни одна из четырёх проблем здесь не применима. Лучше всего подходит для небольших и средних файлов. Для очень больших загрузок см. пункт 2.
  2. Реализовать небольшой Flask-обработчик загрузки с явным контролем размера на каждый запрос (MAX_CONTENT_LENGTH), ограничениями на любое предоставленное клиентом количество частей и белым списком допустимых имён файлов.
  3. Если вы продолжаете использовать dash-uploader, установите MAX_CONTENT_LENGTH на уровне приложения (библиотека этого не делает) и отклоняйте входные данные на уровне приложения или обратного прокси, если выполняется любое из следующих условий:
    • resumableTotalChunks <= 0
    • resumableTotalChunks превышает разумный предел (например, 10 000)
    • resumableTotalSize превышает настроенный разработчиком max_file_size
  4. Добавьте ограничение скорости на конечную точку загрузки на уровне обратного прокси или WAF, чтобы уменьшить вектор OOM при одновременных запросах.
  5. Периодически очищайте потерянные временные каталоги с помощью внешнего cron-задания, поскольку в библиотеке нет внутренней очистки.

График раскрытия

Контекст пакета

  • Приблизительно 28 000 загрузок в месяц на PyPI (27 756 за 30 дней до 2026-05-07, с устойчивым ежедневным объёмом, несмотря на архивацию репозитория). Источник: pypistats.org.
  • Последняя опубликованная версия: 0.6.1 (стабильная линия). Пре-релизы до 0.7.0a2.
  • Обязательная зависимость: dash. Необязательная зависимость: pyyaml. Лицензия: MIT.
  • 11 зависимых пакетов, 6 зависимых репозиториев.
  • 153 звезды на GitHub.
  • Репозиторий заархивирован 2025-07-19 (Issue #153).
  • Ранее CVEs не было (проверено по NVD, GitHub Advisory Database, Snyk, OSV на 2026-03-19).

Ссылки

  • https://www.cve.org/CVERecord?id=CVE-2026-38361
  • https://nvd.nist.gov/vuln/detail/CVE-2026-38361
  • https://github.com/fohrloop/dash-uploader
  • https://github.com/fohrloop/dash-uploader/blob/stable/dash_uploader/httprequesthandler.py
  • https://github.com/fohrloop/dash-uploader/issues/153
  • https://pypi.org/project/dash-uploader/
  • https://pypistats.org/packages/dash-uploader
  • https://libraries.io/pypi/dash-uploader
  • https://pepy.tech/project/dash-uploader
  • https://cwe.mitre.org/data/definitions/400.html
  • https://cwe.mitre.org/data/definitions/670.html
  • https://docs.python.org/3/library/functions.html#all

Обнаружил

Muhammad Fitri Bin Mohd Sultan

Скачать инструмент
CVE IDCVE-2026-38361 (NVD)
УязвимостьНеконтролируемое потребление ресурсов (CWE-400), Всегда некорректная реализация потока управления (CWE-670)
CVSS 3.17.5 / Высокий (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)
Продуктdash-uploader
Затронутые версии0.1.0 – 0.7.0a2 (все 18 релизов)
Исправленная версиянет (проект заархивирован 2025-07-19)
Вектор атакиУдалённо, без аутентификации
ОбнаружилMuhammad Fitri Bin Mohd Sultan
НазначеноMITRE, 2026-05-07
СвязаноCVE-2026-38360 (обход пути в той же библиотеке)
ДатаСобытие
2026-03-19Уязвимости обнаружены в ходе исследования безопасности продакшн-развёртывания.
2026-03-22Запрос CVE отправлен в MITRE.
2026-05-07CVE-2026-38361 назначен MITRE.
2026-05-07Опубликовано публичное уведомление.
2026-05-09Запись CVE опубликована в базе данных CVE MITRE и в NVD.