v0.0.73: фиксы по код-ревью Соннета — SSRF, path traversal, слабый SID, proc_error, zip-бомба, self-XSS
Deploy drhider / validate (push) Canceled after 0s

This commit is contained in:
“Naeel”
2026-08-24 19:58:27 +03:00
parent 4b73657e4c
commit ff4895b63b
7 changed files with 85 additions and 10 deletions
@@ -0,0 +1,39 @@
# 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.