Перейти к содержимому
>_ITDITDПлатформа веб-безопасности

Руководства по безопасности

543 699 учётных данных, опубликованных на GitHub, всё ещё работали (исследование 2026 года): почему нужно отзывать, а не удалять, и что делать разработчикам

Исследование 2026 года нашло в публичных репозиториях 543 699 учётных данных, которые всё ещё работали. Что значат эти цифры, почему удаления недостаточно и что делать: отозвать, проверить использование, заменить.

Опубликовано 2026-10-04 Обновлено 2026-10-04 Последняя проверка 2026-10-04 12 мин чтения

Для кого эта статья: для разработчиков, которые хранят код в публичных репозиториях, например на GitHub, и для компаний, предоставляющих API. Статья своими словами пересказывает цифры из исследования компании по безопасности. Как находить чужие учётные данные, в ней не описывается.

Что это за исследование (не официальное исследование GitHub)

29 сентября 2026 года Truffle Security, компания по безопасности, продающая инструменты поиска секретов, опубликовала исследование учётных данных, оставленных в публичных репозиториях. Как продавец инструментов обнаружения, автор исследования коммерчески заинтересован в этой теме. В этой статье цифры исследования приводятся так, как они опубликованы, а толкование этого сайта отмечено отдельно.

Со стороны GitHub утечки не было. Учётные данные были записаны в код и опубликованы владельцами каждого репозитория. Роль GitHub — предоставлять функции предотвращения, такие как push protection (блокировка push, содержащих секреты), и, как показано ниже, эти функции охватывают ограниченный набор типов.

Как проводилось исследование и как читать цифры

~224,5 млн
Изученных репозиториев (The Stack v3)
27–28 июля 2026
Когда проверялось, действуют ли данные
Только ветка по умолчанию
История коммитов не включена
Аутентификация пройдена
Что значит «действующие» (права и злоупотребления не проверялись)
  • Исходные данные — The Stack v3, набор публичных репозиториев, собранный третьей стороной для обучения LLM (больших языковых моделей). Сбор завершился 7 августа 2025 года.
  • Изучалась только ветка по умолчанию (например, main) на момент сбора. Старые коммиты, другие ветки и всё, что было удалено раньше, не включены. Это не сканирование всего публичного кода на GitHub.
  • «Действующие» означает, что сервис подтвердил: 27–28 июля 2026 года учётные данные всё ещё проходили аутентификацию. Часть из них с тех пор могли отозвать.
  • Время с момента раскрытия отсчитывается от даты последнего изменения файла с учётными данными. В исследовании отмечается, что так реальный возраст обычно занижается.
  • Некоторые типы исключены из части показателей. Ключи Google API проверялись только на Gemini, а закрытые ключи нельзя проверить без хоста, к которому они относятся, поэтому ни те, ни другие не включены в показатели сохранности по типам.

Цифры: что осталось и сколько

543 699
Уникальных учётных данных, действовавших на момент проверки
~1,1 млн
Всего вхождений в файлах и репозиториях
784 дня
Медианное время с момента раскрытия
6,3+ года
Возраст самых старых 10% (самые старые — с 2009 года)

На неделе 29 февраля 2024 года GitHub начал включать push protection по умолчанию для push в публичные репозитории у всех пользователей. Согласно исследованию, 199 843 (36,8%) из 543 699 действующих учётных данных появились после этой даты.

Кроме того, 51,8% действующих учётных данных — это строки подключения, ключи Google API или закрытые ключи, то есть типы, которые push protection по умолчанию не блокирует. Для типов, которые push protection охватывает, число утечек на миллион файлов при сравнении 12 месяцев до и после изменения снизилось примерно на 53%. Для неохваченных типов — лишь примерно на 7%. Само исследование отмечает, что здесь могут смешиваться и другие факторы, например то, что облачные провайдеры в тот же период переводили клиентов на короткоживущие учётные данные.

Сколько сохранилось, по типам

В таблице ниже доли пересчитаны по количествам, опубликованным в исследовании. «Найдено» — число учётных данных, найденных в ветках по умолчанию; «Действует» — сколько из них всё ещё проходили аутентификацию на момент проверки.

ТипНайденоДействуетДоля действующих
Токены npm101 88610,001%
Токены Hugging Face30 437150,05%
Токены GitHub73 0482600,4%
Токены Slack8 9031982,2%
Ключи Stripe (включая ключи тестового режима)124 1324 4933,6%
Ключи доступа AWS82 4116 8198,3%
Токены Docker Hub3 7901 24432,8%
Ключи SendGrid22 8009 18940,3%
Ключи сервисных аккаунтов Google Cloud126 96369 04154,4%
Строки подключения MySQL2 4211 80674,6%
Строки подключения PostgreSQL12 98511 46588,3%
Строки подключения MongoDBНе подсчитано51 067—

Детектор для MongoDB записывает только те строки, с которыми удалось подключиться, поэтому долю рассчитать нельзя, и этот тип исключён из показателей сохранности. Приводится только число действующих.

Почему типы так сильно различаются

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

Выпустивший сервис останавливает их автоматически

  • Токены GitHub: GitHub документирует, что действующие токены, отправленные в публичный репозиторий или gist, отзываются автоматически
  • Токены npm: с 2019 года npm отзывает действующие токены, найденные через GitHub, и пишет владельцу
  • Hugging Face: официальный механизм позволяет любому, а не только владельцу, аннулировать утёкший токен

Остановить их можете только вы

  • Строки подключения к базам данных: выпускающего сервиса нет; они работают, пока вы не смените пароль
  • Многие API-ключи: что сервис делает после уведомления от GitHub, решает сам сервис
  • Закрытые ключи к вашим собственным серверам: только владелец знает, где они используются

Партнёрская программа secret scanning GitHub уведомляет выпустившие сервисы об учётных данных, найденных в публичных репозиториях. Документация GitHub рекомендует считать любой секрет, о котором он сообщает, публичным и скомпрометированным, но реализацию оставляет сервису. Сервис сам решает, отзывать ли, выпускать ли заново или связываться с пользователем.

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

  • AWS: AWS прикрепляет управляемую политику «AWSCompromisedKeyQuarantineV3» к пользователю IAM, чей ключ доступа мог быть раскрыт. Она запрещает определённые действия, например запуск инстансов или изменение IAM, но не удаляет ключ. AWS просит клиентов не удалять эту политику и следовать инструкциям в обращении в поддержку, которое она открывает.
  • Google Cloud: с 16 июня 2024 года ключи сервисных аккаунтов, обнаруженные, например, в публичных репозиториях, по умолчанию отключаются автоматически. Организации могут отказаться от этого (WAIT_FOR_ABUSE) с помощью ограничения политики организации iam.serviceAccountKeyExposureResponse. Исследование всё же нашло больше половины действующими; почему — оно не объясняет.

Взгляд этого сайта: после удаления копии остаются в других местах

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

Поэтому считайте «отправлено в публичный репозиторий» равным «утекло» и аннулируйте учётные данные на стороне выпустившего сервиса. Переписывание истории — это уборка, чтобы остановить дальнейшее распространение.

Ваш репозиторий

Удаление или переписывание истории

→

Форки, клоны, зеркала

На чужих машинах

→

Наборы данных, архивы

Копии на момент сбора

→

Отозвано сервисом

Все копии перестают работать

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

Если вы обнаружили, что допустили утечку

1

Отзовите ключ у выпустившего сервиса

Отключите ключ или токен в консоли или через CLI. Для строки подключения к базе данных смените пароль этого пользователя или создайте пользователя заново. Короткий простой обходится дешевле злоупотребления, поэтому не откладывайте.
2

Проверьте использование и расходы

Ищите незнакомую активность между утечкой и отзывом: CloudTrail в AWS, Cloud Audit Logs в Google Cloud, а также историю использования и счёт в панели сервисов отправки почты или платежей. Если AWS прикрепила политику карантина или открыла обращение в поддержку, следуйте её инструкциям.
3

Выпустите новый ключ и замените старый

Не записывайте новый ключ в код; загружайте его из переменных окружения или менеджера секретов. Воспользуйтесь случаем, чтобы сузить его права, разрешённые IP-адреса источников и срок действия.
4

Историю чистите в последнюю очередь

Удалите ключ из истории инструментом вроде git filter-repo и выполните force push. Копии в форках и на других машинах остаются, поэтому это не заменяет отзыв.

Если нашли чужой ключ, не проверяйте его

Если вы наткнулись на учётные данные в чужом репозитории, не проверяйте, работают ли они. Сообщите владельцу или выпустившему сервису. Для поддерживаемых типов в публичных репозиториях GitHub уведомляет сервис сам.

Как предотвращать утечки

Push protection помогает, но одной её недостаточно. Как показывают цифры, типы, которые она по умолчанию не блокирует, проходят беспрепятственно, а пользователи могут обойти блокировку, выбрав причину. Сочетайте её со следующим.

  • Проверяйте перед коммитом: останавливайте секреты на своей машине до push с помощью сканера вроде gitleaks (см. останавливаем секреты при коммите с gitleaks).
  • Сканируйте историю старых репозиториев: push protection ничего не делает с коммитами, сделанными до её включения. Хотя бы один раз просканируйте полную историю заброшенных и архивных репозиториев.
  • Используйте короткоживущие учётные данные: GitHub Actions может подключаться к AWS или Google Cloud через OIDC (получая учётные данные, действующие лишь короткое время на каждый запуск) вместо хранения долгоживущего ключа. Hugging Face предлагает тот же подход.
  • Сужайте возможности каждого ключа: только чтение, только определённые API, ограничения по IP-адресу источника или referrer и срок действия. Это ограничивает цену утечки.
  • Не выставляйте базы данных в интернет: утёкшая строка подключения бесполезна, если к базе нельзя подключиться снаружи. Строки подключения к базам данных были самым долгоживущим типом в таблице.

Основы того, как не допускать секретов в код, — в статье чем на самом деле опасны .env и API-ключи, а секреты, оставленные на веб-серверах, разобраны в статье проверка публичных каталогов.

Для компаний, предоставляющих API

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

  • Вступить в партнёрскую программу secret scanning GitHub и, получив уведомление, отзывать действующие ключи и сообщать пользователям
  • Давать ключам узнаваемый префикс (например, начинающийся с названия вашего сервиса), чтобы их было легко обнаружить
  • Предоставить канал или API, через который любой может сообщить об утёкшем ключе и аннулировать его
  • Сделать ключи с ограниченным сроком действия и узкими правами вариантом по умолчанию

Источники (открытые данные)

Цифры в этой статье взяты из открытых источников ниже. Текст и графики исследования мы не воспроизводили; использованы только его количества, переупорядоченные нами.

Читать дальше

FAQ

QЭто официальное исследование GitHub?
A

Нет. Его опубликовала 29 сентября 2026 года Truffle Security — компания по безопасности, которая предоставляет инструменты поиска секретов. Со стороны GitHub утечки не было: учётные данные были записаны в код и опубликованы владельцами каждого репозитория. GitHub предоставляет функции предотвращения, такие как push protection и secret scanning, но они охватывают ограниченный набор типов учётных данных.

QЯ закоммитил API-ключ. Достаточно ли удалить файл или переписать историю?
A

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

QРазве выпустивший сервис не отзовёт утёкший ключ автоматически?
A

Зависит от сервиса. В документации GitHub сказано, что действующие токены GitHub, отправленные в публичный репозиторий, отзываются автоматически, и npm с 2019 года делает то же самое для своих токенов. Однако в партнёрской программе secret scanning GitHub то, что сервис делает после уведомления, остаётся на его усмотрение. Учётные данные, за которыми не стоит выпускающий сервис, например строки подключения к базам данных, никто не останавливает.

QРазве push protection в GitHub это не предотвращает?
A

Частично. По умолчанию push protection блокирует определённые форматы токенов, перечисленные в списке поддерживаемых шаблонов. В списке шаблонов GitHub ключи Google API и строки подключения MongoDB и PostgreSQL указаны только как оповещения, без push protection. Кроме того, пользователи могут обойти блокировку, выбрав причину, или отключить функцию. Сочетайте её с проверкой перед коммитом и короткоживущими учётными данными.

QЧто в исследовании значит «действующие»?
A

В исследовании учётные данные находили по шаблонам, а затем 27–28 июля 2026 года спрашивали у каждого сервиса, проходят ли они ещё аутентификацию. Какие у них были права и использовались ли они злоумышленниками, не проверялось. Часть из них с тех пор могли отозвать.