Что делать, когда API-ключи попадают в репозиторий
Вы отправили код на GitHub и через несколько секунд поняли, что вместе с ним ушёл ваш API-ключ. Возможно, GitHub прислал вам уведомление. Возможно, вам написал GitGuardian. В любом случае, теперь вы имеете дело с раскрытыми секретами во фронтенд-приложениях — и время идёт.
Вот что большинство разработчиков делают неправильно: удаление ключа из последнего коммита не решает проблему. История Git сохраняет всё. Форки могли уже появиться. Автоматизированные боты сканируют публичные репозитории в течение нескольких секунд после пуша.
Эта статья подробно описывает, что делать при утечке API-ключей на GitHub, как различать действительно конфиденциальные секреты и публичные клиентские ключи, и как предотвратить повторение подобных ситуаций.
Ключевые выводы
- Немедленно отзывайте и ротируйте раскрытые секреты — очистка истории Git вторична, поскольку ключ уже скомпрометирован.
- Различайте публичные клиентские ключи (предназначенные для использования в браузере) и настоящие секреты (привилегированные учётные данные, требующие срочных действий).
- История Git сохраняет всё, поэтому удаление коммита не удаляет секрет из форков, кешей или существующих клонов.
- Включите защиту от пуша GitHub, чтобы блокировать коммиты с секретами до того, как они попадут в репозиторий.
- Никогда не храните привилегированные ключи во фронтенд-коде — используйте серверные API-маршруты или бэкенд-прокси.
Сначала поймите, что именно вы раскрыли
Не все ключи несут одинаковый риск. Прежде чем паниковать, определите, какой тип учётных данных утёк.
Публичные клиентские ключи предназначены для видимости. API-ключи Google Maps с ограничениями по доменам, токены аналитики или ключи с явным префиксом для клиентской стороны (например, NEXT_PUBLIC_ в Next.js или VITE_ в Vite) предназначены для включения в браузерные сборки. Они всё равно должны иметь ограничения использования, но их раскрытие не катастрофично.
Настоящие секреты предоставляют привилегированный доступ: секретные ключи Stripe, учётные данные AWS, строки подключения к базам данных или любой ключ, который может читать/записывать конфиденциальные данные или приводить к финансовым расходам. Они требуют немедленных действий.
Это различие важно, потому что ваша реакция должна соответствовать серьёзности ситуации.
Немедленная реакция: сначала отзыв и ротация
Когда вы допустили утечку настоящего секрета, очистка истории вторична. Ваш первый приоритет — ротация скомпрометированных API-ключей.
Шаг 1: Немедленно отзовите раскрытый ключ. Войдите в панель управления вашего API-провайдера и удалите или отключите скомпрометированные учётные данные. Не ждите, пока очистите историю Git — ключ уже скомпрометирован.
Шаг 2: Сгенерируйте новый ключ с минимальной областью действия. Применяйте принцип наименьших привилегий. По возможности ограничьте по IP, домену или конкретным API-эндпоинтам.
Шаг 3: Обновите ваше приложение. Разверните новый ключ в ваших окружениях до того, как приложение перестанет работать.
Некоторые облачные провайдеры автоматически отключают учётные данные, обнаруженные в публичных репозиториях. Например, Google Cloud может автоматически отключать раскрытые ключи сервисных аккаунтов по умолчанию. Другие, включая AWS, обычно уведомляют вас, но не всегда автоматически отзывают ключи. Все эти провайдеры участвуют в партнёрской программе сканирования секретов GitHub. Не полагайтесь на автоматизацию — действуйте немедленно в любом случае.
Почему удаления коммита недостаточно
Git никогда не забывает. Даже если вы удалите секрет из текущей ветки, он остаётся в:
- Предыдущих коммитах, доступных через
git log - Форках, созданных до вашего исправления
- Существующих клонах, загруженных другими пользователями или ботами
- Любых зеркалах, созданных до удаления
Вот почему отзыв идёт первым. Очистка истории — это сдерживание, а не исправление.
Если вам нужно очистить историю, могут помочь такие инструменты, как git filter-repo или BFG Repo-Cleaner. Но помните: если ваш репозиторий был публичным хоть какое-то время, считайте, что секрет был перехвачен.
Discover how at OpenReplay.com.
Сканирование секретов и защита от пуша в GitHub
GitHub предлагает первоклассную защиту от этой конкретной проблемы. Сканирование секретов и защита от пуша доступны для всех публичных репозиториев и для приватных репозиториев через GitHub Secret Protection (также входит в GitHub Advanced Security).
Сканирование секретов обнаруживает известные шаблоны учётных данных в вашем репозитории и автоматически уведомляет вас и/или провайдера.
Защита от пуша идёт дальше — она блокирует коммиты с обнаруженными секретами до того, как они попадут в репозиторий. Это самый эффективный механизм предотвращения из доступных.
Включите оба варианта в настройках репозитория в разделе Settings → Code security and analysis или см. официальную документацию по GitHub Secret Protection.
Ловушка переменных окружения фронтенда
Вот ошибка, которая ловит многих разработчиков на React, Vue и Next.js: переменные окружения с префиксом для клиентского использования — это не секреты.
Переменные вроде REACT_APP_*, NEXT_PUBLIC_* или VITE_* включаются непосредственно в ваш JavaScript. Любой может открыть DevTools и найти их. Они не скрыты — они просто организованы.
Если ключ предоставляет привилегированный доступ, он не может находиться во фронтенд-коде. Точка.
Стратегии предотвращения для фронтенд-команд
Храните привилегированные ключи на серверной стороне. Используйте API-маршруты, serverless-функции или бэкенд-прокси. Ваш фронтенд аутентифицирует пользователей; ваш бэкенд хранит секреты.
Включите защиту от пуша. Это перехватывает ошибки до того, как они станут инцидентами.
Используйте pre-commit хуки. Такие инструменты, как gitleaks или detect-secrets, сканируют подготовленные изменения локально.
Добавьте сканирование в CI. Запускайте обнаружение секретов в вашем пайплайне в качестве страховочной сети.
Агрессивно ограничивайте ключи. Даже публичные клиентские ключи должны быть ограничены по домену, IP или области API.
Заключение
Когда происходит утечка API-ключей, скорость важнее совершенства. Сначала отзовите, немедленно ротируйте, затем очистите историю как вторичный шаг. Не путайте публичные клиентские ключи с настоящими секретами и никогда не доверяйте переменным окружения скрывать что-либо во фронтенд-сборках.
Включите защиту от пуша GitHub сегодня. Это самый простой способ гарантировать, что эта проблема больше не повторится.
Часто задаваемые вопросы
Немедленно отзовите или отключите раскрытый ключ через панель управления вашего API-провайдера. Не ждите, пока сначала очистите историю Git. Ключ уже скомпрометирован в момент, когда он был отправлен в публичный репозиторий, и автоматизированные боты могут перехватить его в течение нескольких секунд. После отзыва сгенерируйте новый ключ и обновите ваше приложение.
Нет. Git сохраняет всю историю, поэтому секрет остаётся доступным в предыдущих коммитах, форках, существующих клонах и любых копиях, сделанных до вашего исправления. Удаление или изменение коммита только удаляет его из вершины текущей ветки. Вы должны отозвать ключ независимо от любой очистки истории, которую вы выполните после.
Нет. Эти переменные окружения с префиксом включаются непосредственно в ваш фронтенд JavaScript и видны любому, кто откроет DevTools браузера. Они предназначены для публичных конфигурационных значений, а не для секретов. Любой ключ, предоставляющий привилегированный доступ, должен храниться на серверной стороне и быть доступным через API-маршруты или бэкенд-прокси.
Включите защиту от пуша GitHub, чтобы блокировать коммиты с обнаруженными секретами до того, как они попадут в ваш репозиторий. Используйте pre-commit хуки с такими инструментами, как gitleaks или detect-secrets, для локального сканирования изменений. Добавьте обнаружение секретов в ваш CI-пайплайн в качестве дополнительной страховочной сети. Эти уровни работают вместе, чтобы рано перехватывать ошибки.
Understand every bug
Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.