Files
elmer/doc/audit-2026-06-07.md
T
2026-06-10 15:46:20 +04:00

92 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Отчёт об аудите безопасности и багах (07.06.2026)
## 🔴 КРИТИЧЕСКИЕ (7)
### 1. Жестко заданный API ключ в конфигурации
- **Файл:** [config.yaml](config.yaml#L5)
- **Описание:** \`api_key: "sk-78ec529c1eba4ba69995091046c9fa33"\` — настоящий ключ DeepSeek находится непосредственно в репозитории.
- **Влияние:** Экспозиция платного LLM, финансовый ущерб, возможность несанкционированного использования лимитов.
### 2. check_same_thread=False в SQLite
- **Файл:** [api/db.py](api/db.py#L20)
- **Описание:** Использование \`check_same_thread=False\` без механизмов синхронизации в многопоточном Flask-приложении.
- **Влияние:** Состояние гонки (Race conditions), повреждение базы данных при одновременной записи.
### 3. /api/v1/ping-llm без аутентификации тратит токены
- **Файлы:** [api/ping.py](api/ping.py#L40-45), [web/script_endpoint.py](web/script_endpoint.py#L215-219)
- **Описание:** Эндпоинт доступен без заголовка \`X-Api-Key\` и выполняет реальный запрос к LLM.
- **Влияние:** Возможность DoS-атаки на кошелек API через бесконечные пинги.
### 4. Краш при отсутствии Bluetooth (Android)
- **Файл:** [android/app/src/main/java/ru/elmer/client/ui/MainActivity.kt](android/app/src/main/java/ru/elmer/client/ui/MainActivity.kt)
- **Описание:** Используется оператор \`!!\` для \`btAdapter\`. На устройствах без Bluetooth приложение упадёт.
- **Влияние:** Нестабильность приложения на эмуляторах и старых устройствах.
### 5. Отсутствие аутентификации на критичных эндпоинтах
- **Файл:** [api/routes.py](api/routes.py#L245), [api/routes.py](api/routes.py#L292)
- **Описание:** Эндпоинты \`POST /api/v1/elm/probe\` и \`GET /api/v1/elm/profile/<mac>\` не защищены API-ключом.
- **Влияние:** Идентификация структуры OBD-профилей любых пользователей.
### 6. Дублирование API с разной логикой
- **Файлы:** [web/script_endpoint.py](web/script_endpoint.py) vs [api/routes.py](api/routes.py)
- **Описание:** Маршрут \`/api/v1/session/upload\` реализован дважды. В \`web/\` версии отсутствует проверка идемпотентности (\`request_id\`).
- **Влияние:** Неконсистентное поведение, дублирование LLM-запросов при ретраях из мобильного приложения.
### 7. Состязание потоков в ScriptRunnerService (Android)
- **Файл:** [android/app/src/main/java/ru/elmer/client/script/ScriptRunnerService.kt](android/app/src/main/java/ru/elmer/client/script/ScriptRunnerService.kt)
- **Описание:** Повторный запуск сервиса создает новый поток \`ScriptRunner\`, конкурирующий за Bluetooth-сокет.
---
## 🟡 ВАЖНЫЕ (10)
### 8. Database.close() не гарантирован в web/
- **Файл:** [web/script_endpoint.py](web/script_endpoint.py#L117-120)
- **Описание:** Соединение с БД открывается, но не закрывается в блоке \`finally\`.
- **Влияние:** Утечка дескрипторов файлов и соединений SQLite.
### 9. Отсутствие checkpoint для WAL в SQLite
- **Файл:** [api/db.py](api/db.py#L22)
- **Описание:** Режим WAL включен, но \`wal_checkpoint\` никогда не вызывается явно. Журналы могут расти бесконечно.
### 10. Утечка курсоров в БД (Android)
- **Файл:** [android/app/src/main/java/ru/elmer/client/db/SessionDb.kt](android/app/src/main/java/ru/elmer/client/db/SessionDb.kt)
- **Описание:** Курсоры закрываются только в конце успешных циклов, а не в \`finally\`.
### 11. Не включены Foreign Keys (Android)
- **Файл:** [android/app/src/main/java/ru/elmer/client/db/SessionDb.kt](android/app/src/main/java/ru/elmer/client/db/SessionDb.kt)
- **Описание:** SQLite игнорирует \`REFERENCES\` без явной команды \`PRAGMA foreign_keys = ON\`.
### 12. Раскрытие sensitive info в ошибках
- **Файлы:** [web/script_endpoint.py](web/script_endpoint.py#L127), [api/ping.py](api/ping.py#L48)
- **Описание:** \`str(e)\` пробрасывается клиенту, может содержать детали API или токены.
### 13. Нет лимита на размер payload
- **Описание:** Сервер принимает JSON любого объема, что ведет к OOM (Out Of Memory).
### 14. Нет rate-limiting
- **Описание:** Отсутствует защита от перебора ключей и спама запросами.
### 15. Отсутствие CORS ограничений
- **Файл:** [web/app.py](web/app.py#L48)
- **Описание:** Flask слушает на \`0.0.0.0\`, разрешая запросы с любых источников.
### 16. Уязвимость потокобезопасности AndrOBD
- **Файл:** [obd/protocol.py](obd/protocol.py#L114-121)
- **Описание:** Метод \`send()\` не синхронизирован, состояние протокола может быть повреждено при параллельном доступе.
### 17. Слепой выбор Bluetooth-устройства в сервисе (Android)
- **Файл:** [android/app/src/main/java/ru/elmer/client/script/ScriptRunnerService.kt](android/app/src/main/java/ru/elmer/client/script/ScriptRunnerService.kt#L143)
- **Описание:** Берется первое сопряженное устройство (\`bonded[0]\`), что часто ошибочно.
---
## 📋 ЗАМЕЧАНИЯ ПО АРХИТЕКТУРЕ
- **Dynamic Imports:** В \`web/script_endpoint.py\` импорты используют \`elmer.*\`, что может конфликтовать с установленными пакетами.
- **Git Hygiene:** Файл \`config.yaml\` содержит секреты и должен быть добавлен в \`.gitignore\` с предоставлением \`config.yaml.example\`.
- **Логирование:** Недостаточно информации для трассировки багов пользователя (отсутствуют IP и User-Agent в логах сессий).
---
*Дата аудита: 07.06.2026*
*Инструмент: GitHub Copilot (Gemini 3 Flash)*