hermes-hub/scripts
ochenstarik-ui eac8352dc2 fix(release,web): ворота публикации перестали пропускать всё подряд, /api/action — межсайтовые запросы
P0 аудита, каждый сначала подтверждён исполнением, а не принят со слов.

1. Release Gate объявлял проверку хеша, которой не было. Печаталась строка
   PACKAGE_HASH_VERIFIED=True при том, что hashlib в scripts/release_gate.py
   не вызывался ни разу: скачивались байты 0-10 через заголовок Range, и
   этого хватало, чтобы счесть хеш проверенным. «Проверенным ассетом» при
   этом оказывался первый в списке — checksums.txt, а не пакет.

2. Ворота публикации были fail-open. Измерено в трёх условиях: полный обрыв
   сети -> PASS, манифест 404 -> PASS, пакет 404 -> PASS. Ворота пропускали
   релиз при любом исходе, включая полное отсутствие релиза.

   Разделено на офлайновую часть (проверки 1-7: версии, тесты, updater,
   статика, секреты, список разрешённых адресов) и Publication Gate: релиз
   есть, ассеты есть, пакет скачан ЦЕЛИКОМ, SHA-256 сошёлся с опубликованным
   checksums.txt. Публикационные ворота блокируют в режиме публикации
   (--publication или HERMES_RELEASE_PUBLICATION_GATE=1); в обычном прогоне
   CI, где релиза для ветки нет и быть не должно, результат сообщается как
   есть и не блокирует. Неизмеренное называется причиной, а не выдаётся за
   проверенное. Проверено на живом релизе v0.1.3-b1: два пакета скачаны
   целиком, хеши сошлись.

3. POST /api/action на loopback принимал межсайтовые запросы. Токен там не
   требуется, а действие меняет состояние: удаляет учётные данные, чистит
   аккаунты, переключает маршрутизацию, запускает входы OAuth. CORS от этого
   не защищает — он мешает прочитать ответ, а не отправить запрос. Измерено
   на конфигурации по умолчанию: POST с Content-Type text/plain уходит
   кросс-сайтом без предварительного запроса, request.json() разбирает тело
   независимо от Content-Type, и запрос с Origin чужого сайта без токена
   доходил до исполнителя действий.

   Проверяется Sec-Fetch-Site, при его отсутствии — Origin против адреса
   запроса. Собственный интерфейс, адресная строка и не-браузерные клиенты
   работают как раньше. Защита распространена на все пять небезопасных
   методов, не только на /api/action.

4. pricing fallback: safe_load вместо safe_dump. dump сериализовал текст
   обратно в строку, проверка isinstance(data, dict) не выполнялась никогда,
   таблица цен не загружалась ни разу, а except это глушил.

5. Симуляция Linux в тесте stop_running_hub падала на Windows: os.getuid там
   не существует.

Тесты: 756 -> 776 passed, 2 skipped, 4 deselected. ruff check . чисто.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-03 19:01:30 +07:00
..
build_dist.py refactor(plan-a): close residual blockers, concurrency race, and feed verification 2026-08-20 22:55:43 +07:00
capture_live_a12_screenshots.py feat(ui): A12 — компактные карточки аккаунтов, доступность причин Н/Д, упорядочивание провайдеров и тест службы моделей 2026-08-23 13:30:20 +07:00
capture_live_a14_screenshots.py feat(ui): A14 — компактные карточки аккаунтов, доступность пулов квот и живые скриншоты сценариев 2026-08-23 18:21:20 +07:00
capture_live_a16_screenshots.py feat(web): A16 — веб-клиент без сборки, компактные аккаунты, живые квоты, честная авторизация и скриншоты экранов 2026-08-23 19:37:36 +07:00
capture_live_a18_screenshots.py feat(router): A18 — выбор модели, действие set_model, персистентный кэш и выбор в веб-клиенте 2026-08-23 22:08:08 +07:00
capture_live_a21_screenshots.py feat(web): A21 — паритет веб-интерфейса: аналитика, состояние, события, настройки 2026-08-23 22:59:02 +07:00
check_memory_freshness.py feat(memory): A47 memory freshness checker, tests, and CI/CD contract 2026-08-31 14:57:21 +07:00
enable_lan_access.py fix(launcher): сообщение при запуске не совпадало с настройками; смена токена 2026-08-25 10:47:29 +07:00
generate_branding_assets.py feat: initialize standalone Hermes Hub 2026-08-20 10:53:49 +07:00
generate_provider_assets.py feat(hub): product stabilization, native windows ux v3, provider icons, and architecture roadmap 2026-08-20 11:01:52 +07:00
install.ps1 fix(a54): validate accounts synchronously and manage Windows runtime lifecycle 2026-08-31 20:54:19 +07:00
launch_hermes_hub.bat feat: initialize standalone Hermes Hub 2026-08-20 00:17:11 +07:00
live_provision_and_validate.py fix: repair seven undefined names and make CI ruff step meaningful 2026-08-20 22:28:08 +07:00
release_gate.py fix(release,web): ворота публикации перестали пропускать всё подряд, /api/action — межсайтовые запросы 2026-09-03 19:01:30 +07:00
run_hermetic_tests.py fix(ci): stop hanging hermetic tests and unblock clean/headless runners 2026-08-27 12:03:37 +00:00
setup_local_models.py feat(local): скрипт прописывания локальных моделей и назначения ролей 2026-08-30 21:32:01 +07:00
test_hang_diagnose.py fix(ci): stop hanging hermetic tests and unblock clean/headless runners 2026-08-27 12:03:37 +00:00
uninstall.ps1 feat(installer): A19 — установщики Windows и Linux, запуск веб-интерфейса окном приложения 2026-08-23 22:14:47 +07:00
update.ps1 feat: initialize standalone Hermes Hub 2026-08-20 00:17:11 +07:00
verify_antigravity_provider.py feat: initialize standalone Hermes Hub 2026-08-20 00:17:11 +07:00
verify_multi_provider_router.py fix(security): граница workspace держится одинаково на Windows и Linux 2026-09-03 19:01:30 +07:00