atomic-code-audit-2025-06-29.md 4.7 KB


tags: [audit, bug, security, frontend, backend, code-review]

date: 2025-06-29

Code Audit: 35 найденных проблем (2025-06-29)

Критические (3)

1. Отсутствует go-playground/validator в go.mod

  • backend/go.mod и backend/internal/validator/validator.go:11
  • Пакет импортируется, но отсутствует в go.mod.
  • Фикс: go mod tidy или ручное добавление.

2. Data race на WSHub.clients

  • backend/internal/handlers/websocket.go:83-109
  • broadcastVisitors() итерация по h.clients без мьютекса из двух горутин.
  • Фикс: sync.RWMutex при чтении/записи clients.

3. Утечка маркеров Leaflet

  • frontend/src/lib/map.ts:105-122
  • addMarker не удаляет старый маркер с тем же ID — дубликаты в DOM.
  • Фикс: removeMarker(id) перед addMarker.

Высокие (8)

4. Утечка внутреннего URL MinIO

  • backend/internal/handlers/upload.go:159-164
  • При ошибке url.Parse клиент получает http://minio:9000/....

5. Игнорирование ошибки GetByEmail

  • backend/internal/services/auth.go:85
  • backend/internal/handlers/users.go:113
  • При недоступности БД дубликаты email не проверяются.

6-8. Stale closures в MapView

  • frontend/src/components/MapView.tsx:57-69 — геолокация
  • frontend/src/components/MapView.tsx:100-117 — маркеры мест
  • frontend/src/components/MapView.tsx:121-133 — маркеры посетителей
  • Пропущен user в deps, stale user в замыкании.

9. WebSocket reconnect после unmount

  • frontend/src/hooks/useWebSocket.ts:74-104
  • onclose может сработать после cleanup и запустить reconnect.

10. Presigned upload без проверки ответа

  • frontend/src/app/services/add/page.tsx:39-48
  • fetch() на presigned URL без res.ok.

11. Логи без контекста запроса

  • backend/internal/handlers/errors.go:27
  • Глобальный slog без request_id/user_id.

Средние (10)

12. Игнорирование ошибки тегов сервиса

  • backend/internal/handlers/services.go:79-82

13. Теги сервиса не обновляются

  • backend/internal/handlers/services.go:96-103,167-193

14. Неиспользуемый атомарный rotate token

  • backend/internal/repository/refresh_tokens.go:66-125

15. Нет LIMIT в запросах броней

  • backend/internal/repository/bookings.go:83-107

16. Опчатка detaildetails

  • frontend/src/lib/api.ts:86

17. deleted не в PlaceStatus

  • frontend/src/app/admin/page.tsx:7

18. Falsy-zero для hourlyRate

  • frontend/src/components/PlaceForm.tsx:98-99

19. type в PATCH

  • frontend/src/components/PlaceForm.tsx:93

20. Глотание ошибки API

  • frontend/src/app/places/my/page.tsx:330-336

21. Нет валидации NaN координат

  • frontend/src/components/PlaceForm.tsx:88-89

Низкие (14)

22. useSSL захардкожен

  • backend/cmd/api/main.go:64

23. Неиспользуемая ErrPlaceNotFound

  • backend/internal/services/places.go:47

24. Неиспользуемые валидаторы

  • backend/internal/validator/validator.go:34-35

25. Игнорирование ошибок парсинга query

  • backend/internal/handlers/places.go:62-95

26. cleanup горутина не останавливается

  • backend/internal/middleware/ratelimit.go:29

27. Soft delete сервиса без смены статуса

  • backend/internal/repository/services.go:103

28. Лишний ?. на getBounds

  • frontend/src/components/MapView.tsx:76

29. JSDoc: Яндекс вместо Leaflet

  • frontend/src/components/MapView.tsx:13

30. Избыточный ref

  • frontend/src/components/MapView.tsx:41-42

31. fetchPlaces не в deps

  • frontend/src/app/places/my/page.tsx:338

32. Двойной revokeObjectURL

  • frontend/src/components/PlaceForm.tsx:55-61

33. SetupHandler без интерфейса

  • backend/internal/handlers/setup.go:13-17

34. PlaceHandler хранит authSvc для парсинга

  • backend/internal/handlers/places.go:19-26

35. pointer.Str("") → nil

  • backend/internal/pointer/pointer.go:3-7

Связанные заметки

  • [[MOC-security-patterns]]
  • [[MOC-backend-patterns]]
  • [[atomic-refresh-token-race-condition]]
  • [[atomic-error-swallowing-frontend]]