Предпочтительный канал — приватный отчёт через GitHub: вкладка Security → Report a vulnerability (GitHub private vulnerability reporting). Переписка видна только вам и мейнтейнеру, история сохраняется, и по итогу можно выпустить advisory.
Запасной канал: @ipostatos в Telegram — если приватные отчёты недоступны или вам так удобнее.
⛔ Не открывайте публичные Issues и Pull Requests с описанием уязвимости — они видны всем и превращают находку в готовую инструкцию для атакующего.
Не прикладывайте к отчёту настоящие секреты. Ни токенов бота и ключей API,
ни персональных данных пользователей (Telegram user_id, имена, переписка),
ни копий боевой базы или бэкапов. Для воспроизведения достаточно шагов и
обезличенного примера; если без данных никак — сначала напишите, обсудим
безопасный способ передачи. Присланный настоящий токен придётся считать
скомпрометированным и перевыпускать.
Поддерживается только текущее состояние ветки main и то, что развёрнуто
в проде. Старые коммиты, теги и форки не обслуживаются: исправление выходит
в main, отдельных backport-веток нет.
Что помогает разобраться быстрее:
- что именно происходит и как это воспроизвести;
- какой компонент затронут — бот, Mini App или API синхронизации;
- чем это грозит пользователю (доступ к чужому прогрессу, утечка данных, отказ в обслуживании).
Пожалуйста, не выкладывайте находку публично, пока она не закрыта.
Проект ведёт один человек в свободное время. Ориентир: ответ в течение недели, исправление критичного — как только оно будет готово и проверено. Наград за находки нет; благодарность и упоминание в CHANGELOG — по вашему желанию.
- обход проверки Telegram
initData(HMAC) или доступ к данным чужого пользователя; - SQL-инъекция, path traversal, XSS в Mini App;
- утечка
BOT_TOKENили содержимого базы синхронизации; - отказ в обслуживании, достижимый одним запросом.
- отсутствие rate limit на неаутентифицированных запросах (известно, закрывается на уровне веб-сервера);
- сам факт публичности репозитория и доступности учебного контента —
это лицензионный вопрос, см.
LICENSE; - отчёты автоматических сканеров без подтверждённого сценария эксплуатации.
Не список обещаний, а то, что стоит в коде и проверяется на каждый push:
- подлинность пользователя — строго по Telegram
initData(HMAC,compare_digest);user_idберётся только из проверенной подписи и никогда из тела запроса; - все SQL-запросы параметризованы; слияние состояния идёт в одной транзакции
(
BEGIN IMMEDIATE) — без гонки потерянного обновления; - лимит размера тела запроса проверяется до буферизации (ранний
413); - потолки на объём состояния — подписанный клиент не может залить неограниченный мусор в общий диск;
- сервисы работают от непривилегированной учётной записи; systemd-юниты
захардены (
ProtectSystem=strict, узкиеReadWritePaths,NoNewPrivileges); API слушает только localhost; - деплой не выполняет код и
pipот root; - CI на каждый push: поиск утечённых токенов, запрет на попадание в git
.env, баз и бэкапов, запрет разовыхpip installв деплой-скриптах; - бэкапы БД лежат вне рабочего дерева git, с правами
700/600.
Что именно хранится и зачем — в PRIVACY.md (в боте — команда
/privacy). Коротко: Telegram user_id, прогресс обучения и история
прохождений. Ни сообщений, ни контактов, ни платёжных данных проект не хранит.