Files
drhider/History/code-fixes/2026-08-24-v073-security-fixes.md
T

3.8 KiB
Raw Blame History

v0.0.73 — фиксы по код-ревью Соннета (безопасность + явные баги) (2026-08-24)

code-fixes. По ревью History/sonnet/2026-08-24-code-review-sonnet.md (промпт docs/code-review-sonnet.md). Критично перепроверены в коде; спорные пункты — отклонены/отложены (см. ниже).

Исправлено (6 фиксов)

  1. SSRF (api_bp.py::upload_refs) — добавлена валидация url.startswith(VM_UPLOAD_PREFIX); недоверенный URL пропускается. Константа VM_UPLOAD_PREFIX = "https://contracts.kube5s.ru/drhider-upload/".
  2. Path traversal / zip slip (api_bp.py) — функция _safe_name(): нормализует слэши, отбрасывает .. и абсолютные пути, сохраняя подпапки (Подпапка/Акт.txt → как есть, ../../evil.pdf → ""). Применена в upload и upload_refs. Unit-тест 8 кейсов — все OK.
  3. Слабый SID (session.py) — uuid.uuid4().hex[:12]uuid.uuid4().hex (128 бит).
  4. Серверная ошибка не отображалась — серверное событие event: error (конфликт с встроенным EventSource) → event: proc_error; добавлен клиентский addEventListener('proc_error', …) с показом сообщения.
  5. ZIP-бомба: обход через поддельный file_size (extractor.py) — добавлена проверка total_uncompressed > MAX_UNCOMPRESSED ПОСЛЕ zf.read() с break (ранний выход).
  6. Self-XSS через имя файла (index.html) — добавлена esc() и применена к f.name в rr() и procRow().

Отклонено (критично к Соннету)

  • «cleanup(sid) после /download» — НЕ сделано: ZIP и CSV скачиваются РАЗДЕЛЬНЫМИ запросами; удаление сессии после отдачи ZIP сломало бы скачивание CSV. Сессия и так чистится по TTL (30 мин).

Отложено (требуют решения/риск)

  • idx-мисматч при expand_zips (фильтр расширений на бэке) — связано с фичей v0.0.69 (zip без документов «как есть»), требует решения по поведению.
  • Отмена не проверяется в extract-фазе (.doc liberta 120с) — отдельный фикс.
  • LLM-таймаут тихо обнуляет чанк — логирование/статус.
  • Debug-эндпоинт session_files — ограничить/закрыть.
  • LLM prompt injection — задокументировать (класс риска, не фикс кода).

Проверка

  • py_compile (app.py, api_bp.py, session.py, extractor.py) — OK; node --check — OK.
  • _safe_name unit-тест — 8/8 OK.
  • create_app() стартует (VERSION 0.0.73).
  • Версия 0.0.72 → 0.0.73.

Проверка на проде (редеплой 20:00, v0.0.73)

  • SSRF: POST /api/upload_refs с url=http://169.254.169.254/...{"count":0,"ok":true} (URL отклонён).
  • Path traversal: name="../../evil.txt"{"count":0,"ok":true} (имя отклонено).
  • SID теперь полный 32 hex (128 бит) — виден в ответе.
  • Регресс: папка с подпапкой + кириллицей → «Обработано 2 файлов: 4.3с», в ZIP Подпапка/Договор_1.md + Акт.md (пути сохранены, _safe_name не сломал подпапки).