# Отчёт об аудите безопасности и багах (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/\` не защищены 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)*