Серверы
Управление секретами и ключами: .env, токены и ротация
Где хранить .env, API-токены, пароли от базы и ключи шифрования, кто должен иметь к ним доступ и когда их менять — практическое руководство.
· 8 мин. чтения

Любое веб- и мобильное приложение работает с секретами: пароль от базы данных, APP_KEY, токен SMS- или платёжного провайдера, пароль SMTP, ключи внешних API. Каким бы аккуратным ни был код, одного утёкшего токена может хватить для входа в систему. Поэтому перед экспертизой секреты нужно проверять не по принципу «в коде их нет», а отвечая на вопросы: где они лежат, кто их видит, когда их меняли.
Где живут секреты
Начните с инвентаризации. Обычно секреты находятся:
- в файле
.envна сервере; - в репозитории и его истории (включая старые коммиты);
- в настройках CI/CD и логах сборки;
- в резервных копиях (в архив попадает и
.env); - в логах приложения (вместе с телом запроса или заголовками);
- в сборке мобильного приложения (строки внутри APK/IPA);
- в рабочих чатах и документах.
Составьте простую таблицу для каждого секрета: название, к какой системе даёт доступ, у кого есть, когда последний раз менялся.
1. .env не должен попадать в репозиторий
Проверьте, что .env есть в .gitignore, но этого мало — файл мог быть закоммичен раньше. Просканируйте историю:
gitleaks detect --source . --log-opts="--all"
Если в истории найден настоящий секрет, удалить его из истории недостаточно: копии репозитория могут уже быть в других местах. Правильное решение — заменить секрет (ротация). В .env.example должны быть только имена ключей и пустые или примерные значения.
2. .env не должен открываться из браузера
В Laravel и других фреймворках корнем веб-сервера должен быть каталог public/. Если корень настроен неверно, https://site.uz/.env скачивается напрямую. Дополнительная защита в Nginx:
location ~ /\.(?!well-known) {
deny all;
}
Проверка: curl -I https://site.uz/.env и curl -I https://site.uz/.git/config — оба должны вернуть 403 или 404.
3. Права на файлы
.env должны читать только пользователь, под которым работает приложение, и пользователь деплоя:
chown deploy:www-data .env
chmod 640 .env
Если на одном сервере несколько сайтов, каждый должен работать под отдельным пользователем. Иначе уязвимость одного сайта откроет и секреты соседнего.
4. Принцип наименьших привилегий
Каждый токен должен уметь только то, что нужно:
- приложение подключается к базе не под
rootили суперпользователем, а под пользователем с правами только на свою базу; - ключи внешних API по возможности ограничены по IP или домену;
- там, где нужно только чтение, не выдаются права на запись;
- для теста и production — разные ключи.
Тогда даже при утечке одного ключа ущерб будет ограничен.
5. В логах не должно быть секретов
Логи ошибок часто записывают полное тело запроса: пароль, OTP-код, заголовок Authorization. Настройте уровень логирования для production, маскируйте чувствительные поля и проверьте, что storage/logs не открывается из браузера. APP_DEBUG=false в Laravel — тоже часть этого пункта: отладочная страница может показать переменные окружения.
6. Не храните секреты в мобильном приложении
Распаковать APK или IPA и посмотреть строки внутри несложно. Поэтому не встраивайте в приложение серверные секретные ключи (секретный ключ платёжного провайдера, админский токен) — они должны быть только на бэкенде. По итогам мобильной экспертизы нашего собственного продукта мы убрали хранение endpoint'ов открытыми строками, включили минификацию R8 и Dart --obfuscate, а пользовательские токены перенесли в Keystore/Keychain через flutter_secure_storage. Обфускация усложняет анализ, но не защищает секрет — секрета в приложении не должно быть вовсе.
7. Ротация: когда и как
Ротация — замена секрета новым и отзыв старого. Обязательно выполняйте её, если:
- секрет засветился в репозитории, логе или чате;
- из команды ушёл сотрудник, у которого был доступ;
- на сервере или компьютере сотрудника замечено что-то подозрительное;
- перед экспертизой, если секреты давно не менялись.
Порядок безопасной ротации:
- Создайте новый ключ (в панели провайдера или новый пароль).
- Запишите новое значение в
.envи перезагрузите приложение (php artisan config:cache, перезапуск PHP-FPM и queue worker'ов). - Проверьте, что приложение работает.
- Отзовите старый ключ на стороне провайдера.
- Обновите дату в таблице.
Удаление секрета не делает его безопасным. Утёкший секрет обезвреживается только заменой.
Отдельно про APP_KEY
В Laravel APP_KEY используется для cookie, сессий и данных, зашифрованных через Crypt. Если просто заменить его, активные сессии и зашифрованные поля перестанут читаться. Начиная с Laravel 11 есть переменная APP_PREVIOUS_KEYS: укажите в ней старый ключ, и приложение сможет читать старые данные, а новые шифровать новым ключом.
8. Резервные копии
Архивы резервных копий часто содержат весь каталог проекта, включая .env. Храните их вне веб-корня, шифруйте и ограничивайте доступ. Проверьте, что в public/ не остались файлы вроде backup.zip или site.tar.gz.
Краткий чек-лист
.envнет в репозитории и его истории./.envи/.git/configне открываются из браузера.- Права на
.env—640, владелец верный. - Приложение подключается к базе под ограниченным пользователем.
- В логах нет паролей, токенов и OTP.
- В мобильной сборке нет серверных секретов.
- Для каждого секрета известны владелец и дата последней ротации.
Вывод
Управление секретами начинается не со сложных инструментов, а с порядка: инвентаризация, наименьшие привилегии, закрытие открытых мест и регулярная ротация. Эти пункты дают спокойствие и на экспертизе, и в повседневной работе.
Перед экспертизой Sipar проверяет настройки сервера, репозиторий и сборки в том числе на секреты и закрывает найденные места. Оставьте заявку на сканирование.


