Обновлено: test-контур (docker-compose.test.yml, APP_ENV=test, restore-test) удалён из проекта. Теперь APP_ENV принимает только development/production (валидатор _known_app_env в config.py), поэтому часть задачи про публичный тест-клон с копией прод-данных больше не актуальна. Осталась ситуация с dev.
Проблема
Валидатор Settings._forbid_default_secrets_in_prod (backend/app/core/config.py) останавливает запуск с дефолтными SECRET_KEY / ADMIN_PASSWORDтолько при APP_ENV=production. Для dev это нормально, пока dev живёт на localhost.
Но лаунчер (run.ps1 / run.sh) при LOCAL_PUBLIC=vps выставляет dev на публичный домен https://forbidden-stars.ru через SSH-туннель. В таком режиме наружу открыты:
stub-вход по нику без пароля (POST /api/auth/dev/login). Любой посетитель войдёт под любым пользователем dev-базы; dev_login ищет пользователя по нику без проверки роли;
GET/POST /api/auth/dev/users — список и создание пользователей без аутентификации;
OpenAPI/Swagger (/api/docs) — полная карта API;
с дефолтным SECRET_KEY (change-me-dev-secret-not-for-production виден в репозитории) можно подделать JWT, в том числе админский fs_admin, и дальше вызывать dev-роутер жёсткого удаления аккаунтов DELETE /api/admin/dev/users/{id}.
Данные в dev-базе не прод, но это всё равно публичная точка с обходом аутентификации. Если в dev когда-либо окажется копия прод-данных, они будут открыты.
Что предлагается
При APP_ENV=development + LOCAL_PUBLIC=vps:
предупреждать в лаунчере и в логе старта, что наружу открыт stub-вход и Swagger; или
отключать stub-вход и dev-роутеры, пока dev опубликован (например, enabled_methods() и подключение dev_* в main.py смотрят ещё и на local_public), оставив их для localhost; и/или
применять fail-fast по дефолтным SECRET_KEY/ADMIN_PASSWORD и в этом режиме.
Задокументировать, что у dev и prod должны быть разныеSECRET_KEY.
Найдено при сверке CLAUDE.md с кодом.
> **Обновлено:** test-контур (`docker-compose.test.yml`, `APP_ENV=test`, `restore-test`) удалён из проекта. Теперь `APP_ENV` принимает только `development`/`production` (валидатор `_known_app_env` в `config.py`), поэтому часть задачи про публичный тест-клон с копией прод-данных больше не актуальна. Осталась ситуация с dev.
## Проблема
Валидатор `Settings._forbid_default_secrets_in_prod` (`backend/app/core/config.py`) останавливает запуск с дефолтными `SECRET_KEY` / `ADMIN_PASSWORD` **только при `APP_ENV=production`**. Для dev это нормально, пока dev живёт на localhost.
Но лаунчер (`run.ps1` / `run.sh`) при `LOCAL_PUBLIC=vps` выставляет dev на **публичный** домен https://forbidden-stars.ru через SSH-туннель. В таком режиме наружу открыты:
- **stub-вход по нику без пароля** (`POST /api/auth/dev/login`). Любой посетитель войдёт под любым пользователем dev-базы; `dev_login` ищет пользователя по нику без проверки роли;
- `GET/POST /api/auth/dev/users` — список и создание пользователей без аутентификации;
- OpenAPI/Swagger (`/api/docs`) — полная карта API;
- с дефолтным `SECRET_KEY` (`change-me-dev-secret-not-for-production` виден в репозитории) можно подделать JWT, в том числе админский `fs_admin`, и дальше вызывать dev-роутер жёсткого удаления аккаунтов `DELETE /api/admin/dev/users/{id}`.
Данные в dev-базе не прод, но это всё равно публичная точка с обходом аутентификации. Если в dev когда-либо окажется копия прод-данных, они будут открыты.
## Что предлагается
- При `APP_ENV=development` + `LOCAL_PUBLIC=vps`:
- предупреждать в лаунчере и в логе старта, что наружу открыт stub-вход и Swagger; **или**
- отключать stub-вход и dev-роутеры, пока dev опубликован (например, `enabled_methods()` и подключение `dev_*` в `main.py` смотрят ещё и на `local_public`), оставив их для localhost; **и/или**
- применять fail-fast по дефолтным `SECRET_KEY`/`ADMIN_PASSWORD` и в этом режиме.
- Задокументировать, что у dev и prod должны быть **разные** `SECRET_KEY`.
Найдено при сверке CLAUDE.md с кодом.
Agent
changed title from Проверка дефолтных секретов работает только в production, а публичный test-контур с копией прод-данных не защищён to Dev, выставленный на forbidden-stars.ru (LOCAL_PUBLIC=vps), публичен с stub-входом и без проверки секретов2026-09-14 20:20:54 +03:00
Решения владельца: stub-вход, dev-роутеры и Swagger на публичном dev остаются, но об их открытости нужно явно предупреждать.
config.py: свойство is_published (production либо dev с LOCAL_PUBLIC ≠ local) — на нём же cookie_secure. Fail-fast по дефолтным или слабым SECRET_KEY/ADMIN_PASSWORD срабатывает при is_published, а не только в production.
Предупреждение в лог при старте опубликованного dev: вход по нику без пароля, список и создание игроков, жёсткое удаление аккаунтов, Swagger; совет не держать в dev-БД прод-данные.
То же предупреждение в run.ps1 (ASCII) и run.sh рядом с Public: https://forbidden-stars.ru.
.env.example: что открывает vps; у dev и prod разные SECRET_KEY.
Тесты в test_config_security.py для dev+vps и dev+local.
Модель угрозы. Закрывается вход в админку по общеизвестному паролю и подделка JWT общеизвестным ключом (в том числе админского — и через него жёсткое удаление аккаунтов). Сознательно остаётся вход под любым игроком dev-базы через stub.
Критерии готовности
Опубликованный dev с дефолтными или слабыми секретами не стартует и объясняет почему; localhost-dev стартует с дефолтами, как раньше.
Лаунчер и лог старта перечисляют, что открыто наружу.
pytest зелёный, новые тесты на старом коде падают; run.ps1 без не-ASCII.
Ветка:issue-69-public-dev от dev
## План выполнения
Решения владельца: stub-вход, dev-роутеры и Swagger на публичном dev **остаются**, но об их открытости нужно явно предупреждать.
1. `config.py`: свойство `is_published` (production либо dev с `LOCAL_PUBLIC` ≠ `local`) — на нём же `cookie_secure`. Fail-fast по дефолтным или слабым `SECRET_KEY`/`ADMIN_PASSWORD` срабатывает при `is_published`, а не только в production.
2. Предупреждение в лог при старте опубликованного dev: вход по нику без пароля, список и создание игроков, жёсткое удаление аккаунтов, Swagger; совет не держать в dev-БД прод-данные.
3. То же предупреждение в `run.ps1` (ASCII) и `run.sh` рядом с `Public: https://forbidden-stars.ru`.
4. `.env.example`: что открывает `vps`; у dev и prod разные `SECRET_KEY`.
5. Тесты в `test_config_security.py` для dev+vps и dev+local.
**Модель угрозы.** Закрывается вход в админку по общеизвестному паролю и подделка JWT общеизвестным ключом (в том числе админского — и через него жёсткое удаление аккаунтов). Сознательно остаётся вход под любым игроком dev-базы через stub.
**Критерии готовности**
- Опубликованный dev с дефолтными или слабыми секретами не стартует и объясняет почему; localhost-dev стартует с дефолтами, как раньше.
- Лаунчер и лог старта перечисляют, что открыто наружу.
- `pytest` зелёный, новые тесты на старом коде падают; `run.ps1` без не-ASCII.
**Ветка:** `issue-69-public-dev` от `dev`
Итог: dev на домене (LOCAL_PUBLIC=vps) больше не стартует с дефолтными или слабыми SECRET_KEY/ADMIN_PASSWORD — закрыты вход в админку по известному паролю и подделка JWT. Stub-вход, dev-роутеры и Swagger остаются (решение владельца), а лог старта и лаунчеры предупреждают, что они открыты наружу. Проверки:pytest — 215 passed (6 новых проверок падают на старом коде); ручной старт с дефолтами при vps — понятный отказ; run.ps1 — ASCII. Статус:Status/In Review Осталось за вами: ревью и мёрж PR — задача закроется автоматически. Если в dev-.env дефолтные секреты — заменить до следующего запуска с vps.
Работа выполнена, открыт PR: https://gitea.arseniev.info/NotBigGhost/ForbiddenStarsApp/pulls/92
**Итог:** dev на домене (`LOCAL_PUBLIC=vps`) больше не стартует с дефолтными или слабыми `SECRET_KEY`/`ADMIN_PASSWORD` — закрыты вход в админку по известному паролю и подделка JWT. Stub-вход, dev-роутеры и Swagger остаются (решение владельца), а лог старта и лаунчеры предупреждают, что они открыты наружу.
**Проверки:** `pytest` — 215 passed (6 новых проверок падают на старом коде); ручной старт с дефолтами при `vps` — понятный отказ; `run.ps1` — ASCII.
**Статус:** `Status/In Review`
**Осталось за вами:** ревью и мёрж PR — задача закроется автоматически. Если в dev-`.env` дефолтные секреты — заменить до следующего запуска с `vps`.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Проблема
Валидатор
Settings._forbid_default_secrets_in_prod(backend/app/core/config.py) останавливает запуск с дефолтнымиSECRET_KEY/ADMIN_PASSWORDтолько приAPP_ENV=production. Для dev это нормально, пока dev живёт на localhost.Но лаунчер (
run.ps1/run.sh) приLOCAL_PUBLIC=vpsвыставляет dev на публичный домен https://forbidden-stars.ru через SSH-туннель. В таком режиме наружу открыты:POST /api/auth/dev/login). Любой посетитель войдёт под любым пользователем dev-базы;dev_loginищет пользователя по нику без проверки роли;GET/POST /api/auth/dev/users— список и создание пользователей без аутентификации;/api/docs) — полная карта API;SECRET_KEY(change-me-dev-secret-not-for-productionвиден в репозитории) можно подделать JWT, в том числе админскийfs_admin, и дальше вызывать dev-роутер жёсткого удаления аккаунтовDELETE /api/admin/dev/users/{id}.Данные в dev-базе не прод, но это всё равно публичная точка с обходом аутентификации. Если в dev когда-либо окажется копия прод-данных, они будут открыты.
Что предлагается
APP_ENV=development+LOCAL_PUBLIC=vps:enabled_methods()и подключениеdev_*вmain.pyсмотрят ещё и наlocal_public), оставив их для localhost; и/илиSECRET_KEY/ADMIN_PASSWORDи в этом режиме.SECRET_KEY.Найдено при сверке CLAUDE.md с кодом.
Проверка дефолтных секретов работает только в production, а публичный test-контур с копией прод-данных не защищёнto Dev, выставленный на forbidden-stars.ru (LOCAL_PUBLIC=vps), публичен с stub-входом и без проверки секретовПлан выполнения
Решения владельца: stub-вход, dev-роутеры и Swagger на публичном dev остаются, но об их открытости нужно явно предупреждать.
config.py: свойствоis_published(production либо dev сLOCAL_PUBLIC≠local) — на нём жеcookie_secure. Fail-fast по дефолтным или слабымSECRET_KEY/ADMIN_PASSWORDсрабатывает приis_published, а не только в production.run.ps1(ASCII) иrun.shрядом сPublic: https://forbidden-stars.ru..env.example: что открываетvps; у dev и prod разныеSECRET_KEY.test_config_security.pyдля dev+vps и dev+local.Модель угрозы. Закрывается вход в админку по общеизвестному паролю и подделка JWT общеизвестным ключом (в том числе админского — и через него жёсткое удаление аккаунтов). Сознательно остаётся вход под любым игроком dev-базы через stub.
Критерии готовности
pytestзелёный, новые тесты на старом коде падают;run.ps1без не-ASCII.Ветка:
issue-69-public-devотdevРабота выполнена, открыт PR: #92
Итог: dev на домене (
LOCAL_PUBLIC=vps) больше не стартует с дефолтными или слабымиSECRET_KEY/ADMIN_PASSWORD— закрыты вход в админку по известному паролю и подделка JWT. Stub-вход, dev-роутеры и Swagger остаются (решение владельца), а лог старта и лаунчеры предупреждают, что они открыты наружу.Проверки:
pytest— 215 passed (6 новых проверок падают на старом коде); ручной старт с дефолтами приvps— понятный отказ;run.ps1— ASCII.Статус:
Status/In ReviewОсталось за вами: ревью и мёрж PR — задача закроется автоматически. Если в dev-
.envдефолтные секреты — заменить до следующего запуска сvps.