Руководства по безопасности
543 699 учётных данных, опубликованных на GitHub, всё ещё работали (исследование 2026 года): почему нужно отзывать, а не удалять, и что делать разработчикам
Исследование 2026 года нашло в публичных репозиториях 543 699 учётных данных, которые всё ещё работали. Что значат эти цифры, почему удаления недостаточно и что делать: отозвать, проверить использование, заменить.
Для кого эта статья: для разработчиков, которые хранят код в публичных репозиториях, например на GitHub, и для компаний, предоставляющих API. Статья своими словами пересказывает цифры из исследования компании по безопасности. Как находить чужие учётные данные, в ней не описывается.
Что это за исследование (не официальное исследование GitHub)
29 сентября 2026 года Truffle Security, компания по безопасности, продающая инструменты поиска секретов, опубликовала исследование учётных данных, оставленных в публичных репозиториях. Как продавец инструментов обнаружения, автор исследования коммерчески заинтересован в этой теме. В этой статье цифры исследования приводятся так, как они опубликованы, а толкование этого сайта отмечено отдельно.
Со стороны GitHub утечки не было. Учётные данные были записаны в код и опубликованы владельцами каждого репозитория. Роль GitHub — предоставлять функции предотвращения, такие как push protection (блокировка push, содержащих секреты), и, как показано ниже, эти функции охватывают ограниченный набор типов.
Как проводилось исследование и как читать цифры
- Исходные данные — The Stack v3, набор публичных репозиториев, собранный третьей стороной для обучения LLM (больших языковых моделей). Сбор завершился 7 августа 2025 года.
- Изучалась только ветка по умолчанию (например, main) на момент сбора. Старые коммиты, другие ветки и всё, что было удалено раньше, не включены. Это не сканирование всего публичного кода на GitHub.
- «Действующие» означает, что сервис подтвердил: 27–28 июля 2026 года учётные данные всё ещё проходили аутентификацию. Часть из них с тех пор могли отозвать.
- Время с момента раскрытия отсчитывается от даты последнего изменения файла с учётными данными. В исследовании отмечается, что так реальный возраст обычно занижается.
- Некоторые типы исключены из части показателей. Ключи Google API проверялись только на Gemini, а закрытые ключи нельзя проверить без хоста, к которому они относятся, поэтому ни те, ни другие не включены в показатели сохранности по типам.
Цифры: что осталось и сколько
На неделе 29 февраля 2024 года GitHub начал включать push protection по умолчанию для push в публичные репозитории у всех пользователей. Согласно исследованию, 199 843 (36,8%) из 543 699 действующих учётных данных появились после этой даты.
Кроме того, 51,8% действующих учётных данных — это строки подключения, ключи Google API или закрытые ключи, то есть типы, которые push protection по умолчанию не блокирует. Для типов, которые push protection охватывает, число утечек на миллион файлов при сравнении 12 месяцев до и после изменения снизилось примерно на 53%. Для неохваченных типов — лишь примерно на 7%. Само исследование отмечает, что здесь могут смешиваться и другие факторы, например то, что облачные провайдеры в тот же период переводили клиентов на короткоживущие учётные данные.
Сколько сохранилось, по типам
В таблице ниже доли пересчитаны по количествам, опубликованным в исследовании. «Найдено» — число учётных данных, найденных в ветках по умолчанию; «Действует» — сколько из них всё ещё проходили аутентификацию на момент проверки.
| Тип | Найдено | Действует | Доля действующих |
|---|---|---|---|
| Токены npm | 101 886 | 1 | 0,001% |
| Токены Hugging Face | 30 437 | 15 | 0,05% |
| Токены GitHub | 73 048 | 260 | 0,4% |
| Токены Slack | 8 903 | 198 | 2,2% |
| Ключи Stripe (включая ключи тестового режима) | 124 132 | 4 493 | 3,6% |
| Ключи доступа AWS | 82 411 | 6 819 | 8,3% |
| Токены Docker Hub | 3 790 | 1 244 | 32,8% |
| Ключи SendGrid | 22 800 | 9 189 | 40,3% |
| Ключи сервисных аккаунтов Google Cloud | 126 963 | 69 041 | 54,4% |
| Строки подключения MySQL | 2 421 | 1 806 | 74,6% |
| Строки подключения PostgreSQL | 12 985 | 11 465 | 88,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 года. Если владелец удалил файл после этого, учётные данные всё равно остались в наборе данных. То же касается форков, чужих клонов, зеркал, а также данных для поиска и обучения ИИ.
Поэтому считайте «отправлено в публичный репозиторий» равным «утекло» и аннулируйте учётные данные на стороне выпустившего сервиса. Переписывание истории — это уборка, чтобы остановить дальнейшее распространение.
Ваш репозиторий
Удаление или переписывание истории
Форки, клоны, зеркала
На чужих машинах
Наборы данных, архивы
Копии на момент сбора
Отозвано сервисом
Все копии перестают работать
Если вы обнаружили, что допустили утечку
Отзовите ключ у выпустившего сервиса
Проверьте использование и расходы
Выпустите новый ключ и замените старый
Историю чистите в последнюю очередь
Если нашли чужой ключ, не проверяйте его
Если вы наткнулись на учётные данные в чужом репозитории, не проверяйте, работают ли они. Сообщите владельцу или выпустившему сервису. Для поддерживаемых типов в публичных репозиториях 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, через который любой может сообщить об утёкшем ключе и аннулировать его
- Сделать ключи с ограниченным сроком действия и узкими правами вариантом по умолчанию
Источники (открытые данные)
Цифры в этой статье взяты из открытых источников ниже. Текст и графики исследования мы не воспроизводили; использованы только его количества, переупорядоченные нами.
- Исследование Truffle Security (поставщика инструментов поиска секретов), 29 сентября 2026 года — trufflesecurity.com
- Публикации СМИ: BleepingComputer (30 сентября 2026 года) / SecurityWeek (1 октября 2026 года) / GIGAZINE (2 октября 2026 года, на японском)
- GitHub: push protection включена по умолчанию (GitHub Blog) / About push protection / Supported patterns / Partner program / Token expiration and revocation
- npm: npm Blog (18 июня 2019 года)
- Hugging Face: User access tokens (отзыв утёкшего токена)
- AWS: AWSCompromisedKeyQuarantineV3
- Google Cloud: Automatically disabling leaked service account keys (16 мая 2024 года) / Best practices for managing service account keys
Читать дальше
- Настройки GitHub: как настроить двухфакторную аутентификацию на GitHub
- Предотвращение: останавливаем секреты при коммите с gitleaks / проверка утечки секретов (вставьте текст для сканирования)
- Основы: чем на самом деле опасны .env и API-ключи / что такое файл .env
- Во что может обойтись утечка: код, написанный ИИ, раскрыл API-ключ, и это привело к мошенническим списаниям
- Атаки на учётные данные разработчиков: защита от червей в цепочке поставок / цепочка компрометаций TanStack, Nx Console и GitHub (май 2026)
- Сужение прав ключей: минимальные привилегии для SSH-ключей
FAQ
QЭто официальное исследование GitHub?
Нет. Его опубликовала 29 сентября 2026 года Truffle Security — компания по безопасности, которая предоставляет инструменты поиска секретов. Со стороны GitHub утечки не было: учётные данные были записаны в код и опубликованы владельцами каждого репозитория. GitHub предоставляет функции предотвращения, такие как push protection и secret scanning, но они охватывают ограниченный набор типов учётных данных.
QЯ закоммитил API-ключ. Достаточно ли удалить файл или переписать историю?
После push в публичный репозиторий копии уже могут существовать в форках, чужих клонах, зеркалах и наборах данных вроде того, что использовался в этом исследовании. Удаление файла или переписывание истории эти копии не удаляет. Первый шаг — отозвать ключ у выпустившего его сервиса и выпустить новый. Историю чистите потом.
QРазве выпустивший сервис не отзовёт утёкший ключ автоматически?
Зависит от сервиса. В документации GitHub сказано, что действующие токены GitHub, отправленные в публичный репозиторий, отзываются автоматически, и npm с 2019 года делает то же самое для своих токенов. Однако в партнёрской программе secret scanning GitHub то, что сервис делает после уведомления, остаётся на его усмотрение. Учётные данные, за которыми не стоит выпускающий сервис, например строки подключения к базам данных, никто не останавливает.
QРазве push protection в GitHub это не предотвращает?
Частично. По умолчанию push protection блокирует определённые форматы токенов, перечисленные в списке поддерживаемых шаблонов. В списке шаблонов GitHub ключи Google API и строки подключения MongoDB и PostgreSQL указаны только как оповещения, без push protection. Кроме того, пользователи могут обойти блокировку, выбрав причину, или отключить функцию. Сочетайте её с проверкой перед коммитом и короткоживущими учётными данными.
QЧто в исследовании значит «действующие»?
В исследовании учётные данные находили по шаблонам, а затем 27–28 июля 2026 года спрашивали у каждого сервиса, проходят ли они ещё аутентификацию. Какие у них были права и использовались ли они злоумышленниками, не проверялось. Часть из них с тех пор могли отозвать.