«Постоянно слышу, что безопасность важна, но с чего вообще начать?» Это самый первый шаг для инди-разработчиков. Не чтобы напугать — только то, на что можно действовать сегодня, по порядку.
Почему начинать с секретов (.env и API-ключей)
Большинство реальных инцидентов начинаются не с изощрённых атак, а с утёкшего секрета. Оба случая, на которых построен этот сайт, были утечками секретов:
Защитите свои секреты — и предотвратите большинство частых инцидентов. Поэтому начинаем здесь.
Что такое .env (за 30 секунд)
.env — это файл, собирающий секретные значения вашего приложения: пароль базы данных, внешние API-ключи, ключ, шифрующий сессии. Поскольку секреты лежат вместе в одном файле, утечка раскрывает их все разом — поэтому это файл, который надо охранять первым (→ Глоссарий: Что такое .env).
Где могут храниться секреты (.env, переменные окружения, менеджеры секретов)
.env — не единственное место для секретов. Выбирайте по масштабу и назначению.
| Где | Для чего лучше | На что обратить внимание |
|---|---|---|
Файл .env | Локальная разработка, один небольшой сервер | Держите его вне Git и вне публичных директорий |
| Настройки переменных окружения хостинга (вводятся в панели) | Продакшен | Ограничьте доступ к панели; не допускайте значений в логах сборки |
| Секреты CI (автоматические тесты и деплой) | Автоматизация вроде GitHub Actions | Внешние инструменты, запускаемые в CI, видят значения; передавайте ключи только с нужными правами |
| Менеджер секретов | Несколько человек или несколько серверов | Держите доступ на чтение минимальным и регулярно меняйте ключи |
Для секретов CI полезен пример инцидента Codecov 2021 года. Внешний инструмент, запускаемый в CI, был подменён, и секреты из переменных окружения CI были похищены (→ инцидент Codecov).
Какие ключи можно публиковать, а какие нельзя
Некоторые API-ключи предназначены для использования внутри браузеров или мобильных приложений, другие — только для серверов. Исходите из того, что всё отправленное в браузер может прочитать любой.
| Пример | Можно публиковать? | Почему |
|---|---|---|
Публикуемый ключ Stripe (начинается с pk_) | Да | В документации сказано, что его можно включать во фронтенд-код; он не может выполнять чувствительные операции, например создавать платежи |
Секретный ключ Stripe (sk_) или ограниченный ключ (rk_) | Нет | Они позволяют выполнять серверные операции; документация рекомендует ограниченные ключи с суженными правами |
Переменная окружения Next.js с NEXT_PUBLIC_ | Публикуется | Её значение встраивается в JavaScript для браузера при сборке |
Переменная окружения Next.js без NEXT_PUBLIC_ | Не публикуется (только сервер) | Сюда кладите секретные значения |
Если сомневаетесь, проверьте в официальной документации сервиса, можно ли использовать ключ на стороне клиента. Если там об этом не сказано, считайте ключ непубликуемым.
Что означает утечка API-ключа
API-ключ — это «строка, по которой сервис считает вызывающего вами». В чужих руках ущерб распространяется так.
Украденные ключи часто перепродают и используют с задержкой — «сначала ничего не происходит, потом внезапный счёт» — классический паттерн. Поэтому «после того как заметите» уже поздно; суть в том, чтобы изначально не допустить утечки.
Что делать, если ключ мог утечь
Удаление ключа из кода его не останавливает. По отчёту GitGuardian 2025 года, 70% секретов, утёкших в публичные репозитории в 2022 году, на момент отчёта всё ещё действовали. Действуйте в таком порядке.
- Отзовите или смените ключ в панели выдавшего сервиса. Если сервис даёт льготный период, завершите действие утёкшего ключа «сейчас»
- Установите новый ключ в продакшене и убедитесь, что приложение работает
- Проверьте историю использования и счета у выдавшего сервиса на действия, которые совершали не вы
- Удаление из файлов и истории Git может подождать до отзыва (одно удаление не остановит того, у кого уже есть копия)
Подробнее — в статье 540 000 учётных данных, опубликованных на GitHub, всё ещё действуют. GitHub по умолчанию включает «push protection», которая не даёт личному аккаунту отправить секреты в публичный репозиторий, но ловит она не все виды секретов.
Четыре привычки, чтобы начать сегодня
Ничего сложного. Всего четыре.
Не выставляйте наружу
Никогда не помещайте .env или тело приложения в директорию, видимую из веба (веб-корень). Выставляйте только public/. Конкретные шаги для шаред-хостинга: это руководство.
Не коммитьте
Добавьте .env* в .gitignore (разрешив !.env.example); делитесь только обезличенным примером. Раз закоммитив, его можно восстановить из истории, так что держите его вне с самого начала.
Меняйте всё при утечке
Не только один ключ — меняйте каждый секрет, который мог утечь. По порядку: внешние API / OAuth → ключи шифрования → почта → БД. Действуйте так, будто их видели.
Самопроверка
Время от времени убеждайтесь, что /.env нельзя открыть снаружи (ниже).
Самопроверка (только против доменов, которыми вы владеете)
# 200 с телом означает, что выставлено наружу. 403/404 пока нормально.
curl -sI https://your-domain/.env | head -1
curl -sI https://your-domain/.git/config | head -1Проверка этого при каждом деплое рано ловит ошибки размещения.
Кроме того, что видно снаружи, проверьте также Git и результат сборки (запускайте в своём репозитории).
# Коммитился ли когда-нибудь .env? (любой вывод означает, что да, в какой-то момент)
git log --all --oneline -- .env
# env-подобные файлы, которые Git отслеживает сейчас (всё, кроме .env.example, стоит проверить)
git ls-files | grep -i "env"Чтобы убедиться, что ключ не попадает в браузер, поищите первые несколько символов ключа в папке результата сборки (для Next.js — .next/static). Перед публикацией можно также вставить код в сканер утечки секретов (ничего никуда не отправляется).
Частые ошибки против правильного первого шага
Частое
- «Работает же», и
.envкладут прямо под public - «Потом удалю», и
.envодин раз коммитят - Меняют только тот ключ, по которому видели злоупотребление
Правильный первый шаг
- Тело приложения вне веб-корня, выставлять только
public/ - Исключить
.envчерез.gitignoreс самого начала - При утечке сменить каждый секрет в окружении
Следующие шаги
Дальше следующие темы — «рискованные значения по умолчанию в вашем стеке» и «система, чтобы не отставать от опубликованных CVE». Не спешите, по одной за раз.
Источники
- Next.js, «How to use environment variables in Next.js» (16.x) — nextjs.org
- Stripe Docs, «API keys» — docs.stripe.com
- Laravel 13.x, «Configuration» (Environment File Security) — laravel.com
- GitHub Docs, «About push protection» — docs.github.com
- GitGuardian, «The State of Secrets Sprawl 2025» — blog.gitguardian.com
Читать дальше
- После утечки: 543 699 учётных данных, опубликованных на GitHub, всё ещё действуют — почему нужно отзывать, а не просто удалять
- Утечка Gyazo (сентябрь 2026): что утекло и что пользователям сделать сегодня (на английском)
- Глоссарий: Что такое .env · Что такое CVE · Что такое RCE
- Защита: Держите .env вне публичного веба · Гигиена CVE в Next.js
- Инцидент: Украденный API-ключ и мошеннические счета
- Инцидент: украденный ключ привёл к бану аккаунта
- Цепочка поставок: когда один npm install крадёт ваши учётные данные (на английском; чужой код запускается в среде, где хранятся ваши ключи)