В статье рассказываем, как правильно организовать хранение секретов, чтобы избежать утечек, какие инструменты позволяют автоматизировать процессы и как интегрировать управление секретами в разработку приложений.
В 2022 году злоумышленники проникли в инфраструктуру компании Uber. Они воспользовались тем, что разработчики хранили секреты в коде, и с помощью методов социальной инженерии завладели перепиской, электронными адресами сотрудников и облачными данными. Этот инцидент подорвал доверие клиентов и партнеров, вызвал перебои в работе, а компания потратила миллионы, чтобы устранить последствия и восстановить репутацию.

Как управлять секретами, чтобы избежать утечки данных

24 января 2025
20 минут
эксперт информационной безопасности в Start X
Андрей Жаркевич
автор, люблю технологии, искусственный интеллект и необычные эксперименты
Андрей Огурчиков
автор, люблю технологии, искусственный интеллект и необычные эксперименты
Андрей Огурчиков
эксперт информационной безопасности в Start X
Андрей Жаркевич
Обучение навыкам безопасного поведения

Что такое секреты

Секреты — это конфиденциальные данные, которые защищают доступ к ресурсам, обеспечивают шифрование информации и определяют уровень разрешений для пользователей и сервисов.

Секретами в веб-приложениях могут быть:

  • пользовательские или автоматически генерируемые пароли;
  • API и другие ключи и учетные данные приложений, в том числе внутри контейнеров;
  • SSH-ключи;
  • пароли баз данных;
  • пароли для микросервисов;
  • закрытые ключи для асимметричных систем шифрования.

Скомпрометированный секрет открывает доступ к зашифрованным данным или инфраструктуре и позволяет злоумышленникам получить контроль над системами и данными организации. Чтобы защитить приложения, необходимо хранить секреты в безопасном месте и передавать их только тем пользователям и сервисам, которым они нужны для работы.
Скачайте карту знаний и навыков по безопасной разработке
В ней — 13 уязвимостей и технологий, которые нужно знать разработчику, чтобы писать безопасный код

С какими проблемами сталкиваются компании при управлении секретами

Основной источник проблем с секретами — хранение секретов в коде. 30% всех утечек — попавшие в открытый доступ ключи Google API, в 16% случаев — приватные ключи RSA и другие секреты для инструментов разработки. Абсолютное большинство утечек происходит через репозитории с одним владельцем.

Вот почему у компаний есть проблемы с управлением секретами:

Разработчики не умеют безопасно работать с секретами

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

Секреты никогда не должны храниться в открытом виде, а для их защиты нужно использовать шифрование и хеширование.

Пример использования bcrypt для хеширования паролей:
{
    var hashedPassword = HashPassword(password);
    await using var command = connection.CreateCommand();
    command.CommandText = "INSERT INTO users (username, password) VALUES (@username, @password);";
    command.Parameters.AddWithValue("username", username);
    command.Parameters.AddWithValue("password", hashedPassword);
    await command.ExecuteScalarAsync();
}
async Task<bool> VerifyPasswordAsync(string username, string password, SQLiteConnection connection)
{
    await using var command = connection.CreateCommand();
    command.CommandText = "SELECT password FROM users WHERE username = @username";
    command.Parameters.AddWithValue("username", username);
    var reader = await command.ExecuteReaderAsync();
    if (!reader.Read())
        return false;
    var hashPassword = reader.GetString(0);
        return BCrypt.Net.BCrypt.Verify(password, hashPassword);
}
string HashPassword(string password)
{
    var salt = BCrypt.Net.BCrypt.GenerateSalt();
    var hashedPassword = BCrypt.Net.BCrypt.HashPassword(password, salt);
    return hashedPassword;   
}
В компании нет единой политики и централизованной системы управления секретами

Если в компании нет общей политики управления секретами и централизованной системы их хранения, каждый отдел или даже отдельные сотрудники могут разрабатывать собственные способы работы с ними. Это неудобно: если другим командам или отделам срочно понадобится доступ к какому-либо секрету, они могут долго искать, кто за него отвечает.

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

Хранение секретов в исходном коде в открытом виде

Разработчикам нужно быстро выпускать обновления, поэтому у них часто нет времени, чтобы обрабатывать большие объемы конфиденциальной информации. Они поверхностно осваивают новые технологии и методы безопасности, для ускорения процесса разработки добавляют учетные данные и другие секреты прямо в код, а потом забывают удалить их перед сохранением в репозитории.
Удаление секретов из кода и повторное сохранение изменений в репозитории не исправит ситуацию, потому что история изменений на GitHub может сохранять эти данные. Чаще всего именно это становится причиной утечек.

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

Отсутствие регулярного обновления ключей

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

Недостаточная автоматизация управления секретами

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

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

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

Избыточные права доступа

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

Телеграм-канал Start X

Подписаться
Наши разборы мошеннических схем поймет даже бабушка

Основные сценарии атак на хранилища секретов

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

  • Кража ключей доступа. Самый популярный вектор атаки, при котором злоумышленники целенаправленно сканируют публичные репозитории и выявляют секреты в исходном коде, оставленные разработчиками. Безопасность не гарантируют даже закрытые репозитории, если есть возможность получить доступ к истории коммитов.
  • Эксплуатация уязвимостей инфраструктуры. Хранилища секретов тоже могут стать объектом атаки. При неправильной настройке хранилища злоумышленник может получить доступ к секретам. Например, такое может произойти, если в списках управления доступом не заданы ограничения или привилегированные токены случайно выставлены в pod-объектах Kubernetes. Уязвимости в конфигурациях хранилищ или ошибок в обновлениях могут дать прямой доступ ко всей базе секретов.
  • Ошибки в настройках безопасности. Избыточные права доступа, отсутствие сегментации по ролям и другие недостатки в политиках IAM позволяют пользователям видеть секреты, которые им не требуются. А неправильная настройка сетевых политик может сделать хранилище секретов доступным из внешней сети.

Атаки на основе некорректных конфигураций

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

Еще одна распространенная проблема — доступные публично конфигурационные файлы. Если вы храните секреты в файлах .env или YAML, то рискуете случайно добавить их в репозитории или оставить на общедоступных серверах, например, в хранилищах S3. Если злоумышленник получит доступ к этим данным через публичный S3-бакет, он сможет извлечь учетные данные для баз данных или API.

Для отправки в репозиторий лучше всего готовить файл-шаблон .env.example с заполнителями для конфиденциальных данных. При этом фактический файл .env исключить из контроля версий с помощью.Gitignore. Это гарантирует, что каждый разработчик может создать файл .env с собственными настройками конфигурации, не раскрывая конфиденциальную информацию другим.

Пример использования .env файла:
# Создайте файл .env в корневой директории вашего проекта 
# и добавьте в него секреты в формате "КЛЮЧ=ЗНАЧЕНИЕ"
from dotenv import load_dotenv
import os
# Загрузка переменных среды из файла .env
load_dotenv()
# Получение значения секрета из переменной среды
SECRET_KEY = os.getenv("SECRET_KEY")
# Использование секрета в приложении
print("Секретный ключ:", SECRET_KEY)
Как использовать файл .Gitignore:
Создайте файл .Gitignore для своего репозитория:
touch .Gitignore

Откройте файл .Gitignore в текстовом редакторе и добавьте записи для файлов или каталогов, содержащих пароли и ключи API. Например:
# файл, содержащий секреты
api_keys.txt
# директория с секретами
keys/
# допускается использование wildcard
*key
# Игнорировать файлы переменных среды
.env*

Сохраните изменения в файле .Gitignore и загрузите его в репозиторий:
Git add .Gitignore
Git commit -m "Add .Gitignore to exclude sensitive information"
Git push origin main
Отсутствие сетевых ограничений усиливает риски. Если хранилище секретов доступно из внешней сети и не защищено файрволом, злоумышленник может проникнуть в него через известные уязвимости.

Чтобы защитить хранилище секретов от таких атак, нужно правильно настраивать политики доступа, шифровать данные в конфигурациях, использовать временные токены и регулярно выполнять аудит инфраструктуры.

Статистика утечек секретов в репозиториях GitHub

Регулярную утечку секретов подтверждает анализ публичных репозиториев на GitHub. В течение полугода эксперты просканировали миллиарды файлов, а это 13% всех репозиториев GitHub, и обнаружили, что утечки затрагивают более ста тысяч репозиториев.

В марте прошлого года GitGuardian опубликовала отчет, посвященный проблеме раскрытия секретов в репозиториях GitHub за последние три года. Эксперты пришли к выводу, что тенденция имеет нарастающих характер: в 2023 году она ускорилась на 28% по сравнению с 2022 годом, а всего было раскрыто более двенадцати миллионов секретов.

Кроме того, специалисты GitGuardian установили, что в 2023 году около 5% активно используемых репозиториев раскрыли хотя бы один секрет. Это существенная цифра, учитывая, что компания просканировала около 1,1 млрд репозиториев.

Как безопасно управлять секретами

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

  • Придерживайтесь принципа минимальных привилегий. Каждый пользователь, процесс или сервис должны иметь доступ только к тем секретам, которые нужны для выполнения их задач. Все «лишние» права и доступы лучше удалять.
  • Обеспечьте регулярное обновление секретов. Это снижает угрозу несанкционированного доступа к внутренним ресурсам компании. Старайтесь не использовать статические пароли или ключи. Периодичность обновления секретов всегда индивидуальна, поэтому важно найти баланс между требованиями безопасности и удобством работы сотрудников.
  • Используйте инструменты автоматического управления секретами. Автоматизация управления секретами снижает риск человеческих ошибок, повышает безопасность и упрощает соответствие стандартам, обеспечивает бесшовную интеграцию с инструментами CI/CD и минимизирует вмешательство разработчиков в процессы безопасности. Наиболее популярные инструменты для управления секретами: Azure Key Vault, AWS Secrets Manager, Bitwarden, CyberArk Privileged Access Security, Google Cloud KMS, HashiCorp Vault, Infisical, Thycotic Secret Server, Yandex Lockbox.
  • Журналируйте и анализируйте доступ к секретам. Используйте SIEM-системы для обнаружения подозрительных активностей вроде многократных попыток доступа или использования секретов в неожиданных местах.
  • Отключите запись секретов в журналы. Лучше не сохранять секреты в журналы, настройте логи так, чтобы пароли, ключи API или другие личные данные не попадали в них. Применяйте маскировку, например, для номеров карт, и токенизацию с сохранением структуры.

Научите разработчиков писать безопасный код. На платформе Start EDU подробно объясняем, как безопасно работать с секретами и даем практические задания на поиск уязвимостей в приложениях. Запишитесь на бесплатное демо и наш эксперт расскажет, как Start EDU помогает продуктовым командам предотвращать уязвимости и сразу писать безопасный код.
Мужчина в кресле с ноутбуком

Подпишитесь на дайджест Start X

Еженедельная подборка материалов и аналитики про цифровые атаки на людей, технологии защиты, безопасность инфраструктуры и приложений
Нажимая кнопку «Отправить заявку» вы соглашаетесь с политикой обработки персональных данных.