# Поиск секретов в репозитории _Безопасность · GitLab Knowledge Base_ **TL;DR:** Регулярно сканировать репо на случайно закоммиченные секреты (API-ключи, пароли, токены). Главные инструменты: gitleaks, detect-secrets, trufflehog. Лучше - заранее, в pre-commit. После утечки - ротация ключа неотменимо, чистка истории необязательно. Самая частая security-ошибка в Git - закоммитить API-ключ, пароль БД, AWS credentials. Это считается «утечкой» сразу, как только попало в репо: даже если ты удалил коммитом дальше, файл лежит в истории, доступен `git show :path`, и кто угодно с доступом к репо его прочитает. Если репо публичный - секрет компрометирован за минуты: боты сканируют GitHub и автоматически пытаются использовать найденные ключи. На AWS или похожем cloud-провайдере утёкший ключ способен быстро накрутить заметные расходы (типичный сценарий - запуск тяжёлых EC2/GPU-инстансов под майнинг) ещё до того, как ты заметишь утечку. ## Как защищаться: три слоя ### 1. Не пускать секреты в репо вовсе - `.env`-файлы в `.gitignore` ([gitignore](/courses/git/kb/gitignore.md)). - Secrets из env-переменных, не из файлов. - В коде - placeholder'ы, реальные значения из vault/AWS Secrets Manager/Doppler/1Password. ### 2. Pre-commit hook со scanner'ом Самые популярные инструменты: - **gitleaks** - Go-бинарь, быстрый. Конфиг в `.gitleaks.toml`. - **detect-secrets** (Yelp) - Python, более тонкая настройка через «baseline». - **trufflehog** - Go, сканит даже entropy высокую (находит случайно похожее на токены). Через pre-commit framework ([gpg-signing](/courses/git/kb/gpg-signing.md)): ```yaml # .pre-commit-config.yaml repos: - repo: https://github.com/gitleaks/gitleaks rev: v8.21.0 hooks: - id: gitleaks ``` Теперь коммит с подозрительной строкой блокируется: ``` gitleaks failed: aws-access-key found in src/config.py:15 ``` ### 3. Серверное сканирование - **GitHub Secret Scanning** - встроено для публичных репо бесплатно, для приватных через GHAS (платно). Сканирует на приёме push'а; при найденном ключе автоматически уведомляет провайдера (AWS, Stripe, etc.), и тот может отозвать ключ. - **GitLab Secret Detection** - аналог в SAST-наборе. - **Самодельный pre-receive hook** на bare-сервере, который отвергает push с подозрительными строками. Серверный слой - финальный страховочный сетка. Даже если разработчик пропустил pre-commit (`--no-verify`), серверный scanner поймает. ## Что делать, если утечка уже произошла Прямой порядок действий: ### 1. Ротация ключа - **немедленно** Не «починим историю и потом ротируем». Сначала ротация: - AWS: создать новый access key, удалить старый. - Stripe: revoke API key в дашборде. - GitHub PAT: revoke в Settings. - Любой провайдер: в течение получаса. Это **единственный** способ устранить риск. Чистка истории - это чистота, но не безопасность. ### 2. Уведомить команду Кто-то мог склонировать репо до фикса. Уведомить, что секрет ротирован, чтобы они не пытались использовать старый. ### 3. (Опционально) Чистка истории Если репо приватный и секрет точно не у злоумышленника - можно сократить exposure через [git-filter-repo](/courses/git/kb/git-filter-repo.md): ```bash git filter-repo --replace-text replace.txt # где replace.txt содержит: # AKIA********** ==> [REMOVED] ``` Это переписывает всю историю. После - `git push --force` (нужны права + branch protection временно отключить). Все клоны устаревают, всех просят сделать `git clone` заново. Не делай чистку без ротации - это создаёт ложное чувство безопасности. **Ротация - обязательна, чистка - опциональна.** ## Что чаще всего утекает - **AWS access keys** (AKIA*) - самые распространённые и опасные. - **GitHub PAT/Personal Access Tokens** (ghp_*). - **Stripe/Twilio/SendGrid API ключи**. - **Пароли БД** в `database.yml`, `application.properties`. - **OAuth client_secret** в `.env`-файлах. - **SSH-ключи** в `.ssh/`-копии (см. [ssh-keys-git](/courses/git/kb/ssh-keys-git.md)). - **Сертификаты и приватные ключи** в `.pem`, `.key`, `.crt`. Большинство этих паттернов scanner'ы знают сходу - gitleaks поставляется с правилами на сотни провайдеров. ## Подводные камни - **False positives.** Scanner может посчитать random'ный hash «утекшим ключом». Для detect-secrets есть `--baseline`, который помнит «эти известные, не алертить». - **Старые секреты в истории.** После активации scanner'а на CI он начнёт алертить на старую историю. Стратегия - отдельно почистить старые (или принять как baseline) и потом включить scanner на новые. - **`.env.example` тоже сканируется.** Если в нём вместо placeholder'а реальное значение - scanner поймает. Это норма, держи placeholder'ы (``). ## Команды ```bash gitleaks detect --source . ``` Просканировать репо вручную ```bash git log -p -S 'AKIA' ``` Найти упоминания строки во всей истории (pickaxe) ```bash git filter-repo --replace-text replace.txt ``` Заменить строку во всей истории (после ротации) ## См. также - [.gitignore](/courses/git/kb/gitignore.md) - [git filter-repo: переписывание истории](/courses/git/kb/git-filter-repo.md) - [GPG-подпись коммитов](/courses/git/kb/gpg-signing.md)