# Production security review Проверка выполнена 7 сентября 2026 года и актуализирована для открытой альфы. Она охватывает код и Compose-конфигурацию; firewall, SSH, DNS и фактические права файлов проверяются отдельно на целевом сервере. ## Закрытые пункты | Область | Реализация | |---|---| | Внешняя поверхность | наружу публикуются только Caddy `80/443`; PostgreSQL, API, web и MinIO находятся во внутренних сетях | | Admin web/API | `/admin/*` требует Caddy Basic Auth; `/api/v1/admin/*` требует длинный Bearer-токен в FastAPI. Схемы разделены по маршрутам, поскольку используют один заголовок Authorization (T02, 9 сентября) | | Сравнение токена | constant-time `hmac.compare_digest` | | CORS | production принимает только явно заданные HTTPS origins, wildcard запрещён конфигурацией | | Чувствительные ответы | административные ответы и создание заявки получают `Cache-Control: no-store` | | Browser headers | HSTS, `nosniff`, restrictive referrer/permissions, anti-framing CSP/X-Frame-Options и COOP | | Скриншоты | MIME/расширение/фактический формат, лимит размера и пикселей, повторное кодирование без EXIF, одноразовый upload token | | MinIO | Console не опубликована; root credentials отделены от application credentials и не передаются API | | Секреты | production fail-fast отклоняет короткие/демонстрационные значения; `.env.production` исключён из Git и должен иметь mode `0600` | | Контейнеры | API и web запускаются непривилегированными пользователями; для всех сервисов включён `no-new-privileges` | | Логи | query string, IP, Authorization и payload не журналируются; известные формы секретов редактируются | | Персональные данные | действует документированная retention-очистка, причём backup выполняется раньше удаления | ## Остаточные риски открытой альфы - Basic Auth и bearer token общие для всех модераторов: персональная атрибуция и отзыв одной учётной записи отсутствуют. - Нет MFA и отдельного identity provider; admin credentials следует передавать только ограниченному числу операторов и ротировать при любом подозрении. - Application user MinIO имеет встроенную политику `readwrite`; сейчас в инстансе используется один прикладной bucket. Перед появлением других bucket нужна отдельная bucket-scoped policy. - Пользователь `rf4spotter`, запускающий Docker/systemd, фактически обладает высокими правами через Docker socket. SSH к нему должен быть ограничен ключами и firewall/VPN. - Защита от volumetric DDoS и внешний WAF не входят в single-server Compose. ## Проверка на сервере 1. Убедиться, что `ss -lntup` не показывает наружу порты `4321`, `8000`, `9000`, `9001`, `5432`. 2. Проверить `stat -c '%a %U:%G' .env.production`: ожидается `600 rf4spotter:rf4spotter`. 3. Без Basic Auth запрос к `/admin/moderation` должен вернуть `401` от Caddy; с правильным Basic — `200`. Bearer не открывает административную страницу. 4. Admin API без Bearer, с неверным Bearer или только с Basic должен вернуть `401` от FastAPI; правильный Bearer даёт доступ и `Cache-Control: no-store`. Владение API-токеном достаточно для API-доступа; дополнительная Basic-проверка к этим запросам не применяется. 5. Проверить security headers через `curl -I https://rf4spotter.ru/`. 6. Убедиться, что `https://files.rf4spotter.ru/` не открывает Console, list buckets или анонимную запись. 7. После проверки удалить команды с секретами из shell history либо вводить их через защищённый password manager. Локальная проверка: `sh deploy/test-proxy-routing.sh` запускает временный Caddy с production-маршрутами перед работающим Compose. `probe-admin-auth.py` читает токен из окружения API-контейнера и не печатает его. Проверяются успешное чтение, отказы и PATCH с невалидным UUID без изменения данных; полный цикл реальной модерации через proxy относится к T06.