Утечки секретов в Git: как найти забытые API-ключи

—

от автора

Представим ситуацию: разработчик торопится закрыть задачу, вставляет API-ключ прямо в конфиг, делает коммит и пушит изменения в репозиторий. Через неделю ключ убирают из кода, задача закрывается, все довольны.

Но есть нюанс: удаление строки из актуальной версии проекта не означает, что секрет исчез из истории Git.

Если репозиторий доступен публично, ключ может обнаружиться спустя месяцы. А если он даёт доступ к облачной инфраструктуре, базе данных или стороннему API, последствия могут оказаться весьма неприятными.

— Разберёмся, как искать такие утечки и автоматизировать проверку, чтобы не заниматься разгребанием инцидентов постфактум.

Где обычно прячутся секреты

Начнём с классики. К чувствительным данным, которые не стоит хранить в открытом виде в репозитории, относятся:
— API-ключи и токены доступа;
— пароли от баз данных;
— приватные SSH-ключи;
— учётные данные для облачных сервисов;
— секреты для интеграций и вебхуков;
— файлы «.env» с конфигурацией приложения.

Причём искать нужно не только в исходниках. Секреты могут оказаться в конфигурационных файлах, тестовых данных, скриптах развёртывания и старых коммитах.

Именно поэтому обычный поиск по текущему содержимому проекта не всегда помогает.

Знакомимся с Gitleaks

Для поиска секретов в Git можно использовать Gitleaks — инструмент, который анализирует репозитории и выявляет строки, похожие на чувствительные данные.

Он работает по набору правил и позволяет проверять как локальные проекты, так и историю коммитов.

Документация и установка доступны в официальном репозитории: https://github.com/gitleaks/gitleaks

После установки можно проверить проект командой:

gitleaks git .

Она запускает проверку Git-репозитория в текущем каталоге.

Если нужно проверить отдельный каталог с исходниками, не привязанный к Git, можно использовать:

gitleaks dir .

Обнаруженные совпадения инструмент выводит в отчёт. В зависимости от версии и параметров запуска там могут быть указаны файл, строка и другие сведения о находке.

Важный момент: обнаружение подозрительной строки ещё не означает, что это действующий секрет. Иногда инструмент находит тестовые значения, заглушки или обычные строки, которые лишь похожи на ключи.

Поэтому результаты нужно проверять вручную.

Почему удалённый ключ всё ещё может быть проблемой

Допустим, разработчик добавил секрет в коммит:
git add .
git commit -m «Add API integration»
git push

Позже он удалил ключ из файла и отправил изменения повторно.

В актуальной версии кода секрета уже нет. Но предыдущий коммит никуда не делся, и его содержимое всё ещё может быть доступно через историю Git.

Поэтому при расследовании важно проверять не только рабочую директорию, но и историю репозитория.

Gitleaks умеет работать с историей Git. Это особенно полезно при аудите старых проектов, которые долго развивались без автоматических проверок.

И ещё один нюанс: если секрет попал в публичный репозиторий, нельзя считать его безопасным только потому, что он находился там несколько минут. Автоматические сканеры могут обнаруживать новые коммиты практически сразу.

Как не допускать утечек в будущем

Разовые проверки полезны, но лучше встроить поиск секретов непосредственно в процесс разработки.

Есть несколько простых шагов.

1. Использовать переменные окружения.

Вместо хранения ключей непосредственно в коде лучше передавать их через переменные окружения или специализированное хранилище секретов.

Например, в Python:

import os

api_key = os.environ[«API_KEY»]

Так секрет не приходится прописывать непосредственно в исходном файле.

При этом сами переменные окружения тоже нужно правильно защищать: их значения могут попасть в логи, дампы процессов или диагностические отчёты.

2. Добавить проверку перед коммитом.

Gitleaks можно использовать для локальной проверки проекта перед отправкой изменений.

Это позволяет обнаруживать потенциальные утечки раньше, чем они попадут в удалённый репозиторий.

3. Встроить сканирование в CI/CD.

Автоматическую проверку можно запускать при каждом изменении кода. Если обнаружен секрет, сборка или проверка должны завершаться с ошибкой.

В результате разработчик узнает о проблеме ещё до развёртывания приложения.

4. Не полагаться исключительно на «.gitignore».

Добавление файла «.env» в «.gitignore» помогает избежать случайного добавления новых файлов в репозиторий. Но оно не удаляет файл, который уже отслеживается Git, и не очищает историю коммитов.

Если секрет уже попал в репозиторий, нужны дополнительные действия.

Что делать, если секрет всё-таки утёк

Допустим, сканер обнаружил действующий API-ключ в старом коммите. Что дальше?

Прежде всего, необходимо отозвать или заменить ключ. Простое удаление строки из кода не лишает злоумышленника возможности использовать уже скомпрометированные учётные данные.

Затем стоит:

— проверить журналы использования ключа на предмет подозрительной активности;
— оценить, какие ресурсы и данные могли быть доступны через него;
— удалить секрет из актуальной версии кода;
— при необходимости очистить историю репозитория и синхронизировать изменения с его копиями;
— добавить автоматические проверки, чтобы ситуация не повторилась.

Очистка истории сама по себе не заменяет отзыв ключа: старые коммиты могут сохраниться в клонах, форках и других копиях репозитория.

Главное правило: если секрет оказался доступен посторонним, считайте его скомпрометированным, пока не доказано обратное.

Вместо заключения

Утечки секретов в Git — не какая-то экзотическая угроза. Они возникают из-за обычных ошибок в процессе разработки: кто-то забыл убрать ключ, кто-то закоммитил конфигурацию, а кто-то решил, что удалённая строка больше никому не доступна.

Gitleaks помогает находить подобные проблемы, но сам по себе не решает их полностью.

Оптимальный подход — регулярно сканировать репозитории, проверять историю коммитов, хранить секреты отдельно от исходного кода и встроить автоматические проверки в CI/CD.

Потратить несколько минут на настройку сканера обычно проще, чем потом разбираться, кто и зачем использовал ваш API-ключ.

Мы в Telegram: https://t.me/+jAjZcfEdOx42NzRi

ссылка на оригинал статьи https://habr.com/ru/articles/1103478/