3.1 KiB
3.1 KiB
Endpoint SQL-запросов к БД (/v2/db/query)
Создан: 2026-07-08
Назначение
Дать DevOps-инженеру (одному человеку, заданному через ADMIN_EMAIL) возможность выполнять SQL-запросы к БД напрямую из браузера — без psql, без kubectl, без внешнего IP.
Доступ
- Только один пользователь:
req.email === ADMIN_EMAIL - Обычный юзер сервиса (проходит SSO как все)
- Пример:
ADMIN_EMAIL=atazet@narod.ru
Адрес
GET /v2/db/query?sql=<часть запроса после SELECT>
Как работает
- Пользователь заходит в сервис через SSO (любой URL, например
/v2/app) - Меняет в адресной строке путь на
/v2/db/query?sql=... - Сервер:
- Проверяет сессию (resolveContext)
- Проверяет что
req.email === ADMIN_EMAIL - Добавляет префикс
SELECTперед вводом пользователя - Выполняет:
pool.query('SELECT ' + userInput) - Возвращает JSON
Примеры
| Ввод в браузере | Что выполняется |
|---|---|
/v2/db/query?sql=* FROM _migrations |
SELECT * FROM _migrations |
/v2/db/query?sql=count(*) FROM companies |
SELECT count(*) FROM companies |
/v2/db/query?sql=* FROM whitelist_entries LIMIT 10 |
SELECT * FROM whitelist_entries LIMIT 10 |
/v2/db/query?sql=* FROM audit_log ORDER BY created_at DESC LIMIT 5 |
SELECT * FROM audit_log ORDER BY created_at DESC LIMIT 5 |
Безопасность
-
SELECT префикс — жёстко добавляется
SELECTперед вводом пользователя. DROP/INSERT/UPDATE/DELETE не работают:/v2/db/query?sql=DROP TABLE companies → SELECT DROP TABLE companies (ошибка SQL, не выполнится) -
Одиночные запросы — драйвер
pgне поддерживает множественные запросы в одномquery(). Попытка1; DROP TABLEне сработает. -
Доступ по email — только один человек, заданный в
ADMIN_EMAIL. -
Rate limiter — endpoint защищён лимитером (как mutationLimiter).
Ответ
{
"rows": [ ... ],
"rowCount": 5,
"fields": ["id", "filename", "applied_at"]
}
Реализация
- Файл:
v2/src/db/query.js - Middleware:
resolveContext+ проверкаreq.canQueryDB - Роутер монтируется в
v2/server.jsна/db - Флаг
req.canQueryDBвыставляется вv2/src/router/index.js(applyContext)
Ограничения
- Только SELECT (через префикс)
- Нет GUI — только JSON в браузере
- SQL в URL (логируется в access_log nginx/ingress — это нормально для devops-инструмента)