Files
rf4-spotter/docs/security-review.md
T
ik c6fdc969c2
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
fix: separate admin page and API authentication
2026-09-09 07:29:39 +07:00

5.6 KiB
Raw Blame History

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.