Почему люди хранят пароли и ключи прямо в коде и как навести порядок

Почему люди хранят пароли и ключи прямо в коде и как навести порядок

изображение: recraft

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

Почему так получается

  • «Впишу на пять минут»

Это классика: чтобы проверить интеграцию, легче вставить ключ прямо в код, чем поднимать инфраструктуру для секретов. Разработчик честно собирается его потом убрать, но коммит уходит в ветку, эта ветка мержится в основную, и «потом» не наступает никогда.

  • Правильный путь vs удобный

Чтобы локально запустить проект как положено, придется получить доступ к хранилищу секретов, настроить аутентификацию, разобраться с CLI и попросить у DevOps подходящую роль. Но можно поступить иначе: просто вписать строку в конфиг и запуститься через тридцать секунд. Пока второй вариант на порядок удобнее первого, люди будут выбирать именно его, и дело в экономии усилий, а вовсе не в дисциплине.

  • Документация учит плохому

В README половины библиотек написано:

client = Client(api_key=»sk-…»)

Человек это копирует, подставляет свой ключ и идет дальше. Этот паттерн документация ежедневно выдает всем, однако в примере никто не написал os.environ[«API_KEY»], потому что так этот пример станет менее наглядным.

  • Непонимание того, как устроен git

Git rm, новый коммит, «я почистил» – а секрет при этом остался в истории. Он доступен через git log -p, «уехал» в форки и есть в каждом клоне у любого разработчика. Иллюзия чистоты опаснее самого секрета, ведь что из-за нее никто не станет отзывать ключ.

Чем это опасно

Приватный репозиторий – не защита. Причин много: компрометация аккаунта разработчика, недовольный инсайдер, случайное переключение видимости или зеркало репозитория в CI-системе с более слабым контролем доступа. Приватность – это просто одно кольцо защиты, а не гарантия безопасности.

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

Docker-образы «протекают». Docker history показывает команды сборки, а распаковка слоев – файлы. Тот секрет, что вы аккуратно удалили в следующем слое, никуда не делся из предыдущего. Слои иммутабельны, и удаление в Docker – просто пометка «этого файла больше нет», а не стирание данных на самом деле.

Что делать, если секрет уже «утек»

Вот самый грамотный порядок действий, и их очередность имеет большое значение:

  1. Отозвать секрет у провайдера, причем немедленно – до чистки истории, разговоров с командой и расследования. Скомпрометированный ключ должен перестать работать.
  2. Выпустить новый через нормальный процесс и с хранением в надежном месте.

Только потом чистить историю через git filter-repo. Важно понимать, что чистка истории опциональна: это force push, переписывание всех хешей, боль для каждого, у кого есть клон или открытый PR. Более того, она ничего не гарантирует: секрет мог «осесть» в форке, кеше хостинга, логах CI, чьем-то локальном репозитории или поисковом индексе.

Ротация – единственное надежное действие, все остальное – просто гигиена.

Как предотвратить проблему

  • Найти то, что уже есть

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

  • Не полагаться на дисциплину разработчиков

Pre-commit хуки – хорошая идея, но у нее есть фатальный недостаток: они «живут» на машине у конкретного человека и не появятся у нового сотрудника автоматически. Их можно по каким-то причинам не установить, а еще они обходятся через —no-verify.

Работающий вариант – проверка на стороне сервера. Серверные `pre-receive` хуки в GitFlic выполняются при получении пуша до того, как коммиты попадут в репозиторий. Разработчику не надо ничего настраивать локально, обойти проверку нельзя, а покрытие получается стопроцентным для всех репозиториев, где хук включен.

Разница принципиальная: pre-commit – это напоминание, а pre-receive – уже правило. Секрет, который не прошел серверную проверку, физически не попадет в историю, а значит, не будет ни filter-repo, ни force push, ни вопроса «а точно ли мы все почистили».

  • Хранить секреты там, где им и место

Запретить секреты в коде можно, только когда их есть куда положить. Эту задачу решает Vault или другое централизованное хранилище: секреты находятся в одном месте, есть версионирование, аудит доступа и возможность отозвать ключ у нужного сервиса, не трогая остальные.

У GitFlic интеграция с Vault сделана, и это закрывает главную проблему, о которой шла речь в начале статьи – экономию усилий. Если получить секрет из хранилища в CI-пайплайне так же просто, как вписать в конфиг, для вписывания «на пять минут» пропадает мотивация.

Итог

Секреты попадают в код не потому, что люди не знают, что так нельзя. Просто правильный путь требует усилий, а неправильный – нет, документация нормализует плохой паттерн, а модель хранения истории в git интуитивно неочевидна. Значит, вместо чтения лекций лучше:

  • просканировать существующие репозитории (gitleaks) и отротировать все найденное;
  • поставить серверные `pre-receive` хуки – в GitFlic это делается на уровне сервера без участия каждого разработчика;
  • дать нормальную альтернативу – интеграцию с Vault, чтобы правильный путь стал самым коротким.

И помните главное: если секрет «утек» – сначала отзыв и только потом все остальное. История переписывается, а ключ – нет.

Эдуард Тихомиров, технический директор GitFlic (входит в «Группу Астра»)

Группа Астра
Автор: Группа Астра
ГК «Астра» (ООО «РусБИТех-Астра») — один из лидеров российской IT-индустрии, ведущий производитель программного обеспечения, в том числе защищенных операционных систем и платформ виртуализации. Разработка флагманского продукта, ОС семейства Astra Linux, ведется с 2008 года. На сегодня в штате компании более 1000 высококвалифицированных разработчиков и специалистов технической поддержки.
Комментарии: