FINDINGS.md 5.7 KB

Findings: Аудит проекта PhotoPlaces

Дата аудита: 2026-06-13


1. Безопасность

🔴 P0: websocket.go — CheckOrigin всегда true

backend/internal/handlers/websocket.go:13 — WebSocket принимает соединения с любых источников. В production должен проверять AllowedOrigins.

CheckOrigin: func(r *http.Request) bool { return true }

🔴 P0: places.go — ошибка авторизации не типизирована

backend/internal/services/places.go:118 — использует fmt.Errorf("not your place") вместо sentinel error. Вызывающий код не может отличить "не ваше место" от других ошибок.

🔴 P0: Dev-секреты в docker-compose.yml

Локальный docker-compose.yml содержит:

  • POSTGRES_PASSWORD: photoplaces_dev
  • REDIS_PASSWORD: photoplaces_dev
  • MINIO_ROOT_PASSWORD: photoplaces_dev
  • JWT_SECRET: dev-secret-change-in-production

Риск: если запустить docker compose up без переопределения секретов, они уходят в production.

🔴 P0: env.prod с placeholder-секретами

deploy/env.prod:

  • DB_PASSWORD=CHANGE_ME_STRONG_PASSWORD
  • REDIS_PASSWORD=CHANGE_ME_REDIS_PASSWORD
  • JWT_SECRET=CHANGE_ME_JWT_SECRET_32_HEX
  • S3_SECRET_KEY=CHANGE_ME_MINIO_PASSWORD
  • YANDEX_MAPS_API_KEY=ВАШ_КЛЮЧ_ЯНДЕКС_КАРТ

Риск: деплой с этими значениями провалится, но если кто-то скопирует env.prod на другой сервер — будет дыра.

🟡 P1: backend/cmd/api/main.go — rate limiter in-memory активен

Несмотря на наличие ratelimit_redis.go, в main.go используется in-memory rate limiter. Redis-версия не подключена.


2. Баги

🔴 P0: log.go:114string(rune(line)) вместо strconv.Itoa(line)

Исправлено. Функция callerInfo конвертировала номер строки в символ Unicode, а не в строку.

🟡 P1: strPtr дублируется

Определена дважды:

  • backend/internal/handlers/helpers.go:7
  • backend/internal/services/auth.go:252

Риск: при изменении одной копии вторая рассинхронизируется.

🟡 P1: reviews.go — самописные утилиты вместо стандартных

backend/internal/handlers/reviews.go:88-103:

  • isUniqueViolation — ручной парсинг ошибки pgx, когда есть pgconn.PgError
  • contains, searchString — дубликат strings.Contains

3. Тесты

🔴 P0: 0 тестов во всём проекте

  • make test-backendgo test ./... ничего не найдёт
  • make test-frontendnpm run test упадёт (нет скрипта в package.json)
  • frontend/package.json не содержит "test" скрипта

Стратегия тестирования описана в obsidian_data/Photoplaces_data/decision-test-strategy.md, но не реализована.


4. Архитектура / Незавершённое

🟡 P1: Только Яндекс.Карты

frontend/src/lib/map.ts — интерфейс MapProvider есть, но реализован только Yandex Maps. MapLibre/OSM (из docs/MAP_PROVIDERS.md) не реализованы.

🟡 P1: Redis rate limiter не подключён

backend/cmd/api/main.go использует in-memory ratelimit.go. ratelimit_redis.go написан, но не включён. Решение в Obsidian (decision-rate-limiter-redis.md) помечено как "Accepted (needs implementation)".

🟡 P2: env.prod с хардкодом IP

S3_PUBLIC_ENDPOINT=http://192.168.88.128:9000 — IP зашит, а не домен. При смене сервера требует ручного редактирования.


5. Документация (исправлено)

✅ Go package-level docs

Добавлены во все 8 пакетов:

  • main, config, log, validator, models, handlers, middleware, repository, services

✅ Frontend JSDoc

Добавлены ко всем экспортам: 18 файлов, все компоненты, хуки, типы, утилиты.

✅ CONTRIBUTING.md

Создан.

✅ README.md

Уже был, полный и актуальный.


6. Рекомендации

Приоритет 0 (немедленно)

  1. Заменить CheckOrigin: return true на проверку ALLOWED_ORIGINS
  2. Заменить fmt.Errorf("not your place") на sentinel error ErrNotYourPlace
  3. Написать хотя бы 1 smoke-тест для health endpoint
  4. Заменить placeholder-секреты в deploy/env.prod на сгенерированные
  5. Убрать dev-секреты из docker-compose.yml (вынести в .env)

Приоритет 1 (до production)

  1. Удалить дубликат strPtr из services/auth.go, использовать из helpers.go
  2. Заменить самописные contains/searchString на strings.Contains
  3. Подключить Redis rate limiter вместо in-memory
  4. Заменить IP в env.prod на доменное имя

Приоритет 2 (улучшения)

  1. Реализовать MapLibre/OSM провайдер для карт
  2. Настроить "test" скрипт в frontend/package.json
  3. Добавить npm run test в CI