Защита корпоративного VCS/GitLab Comminity edition: контроль форков, секреты в истории коммитов и политика ревью для чувствительных репозиториев

Защита корпоративного VCSGitLab Comminity edition: контроль форков, секреты в истории коммитов и политика ревью для чувствительных репозиториев

Изображение: grok

Системы управления версиями кода (Git, GitLab, Gitea и аналоги) стали критичной инфраструктурой для большинства компаний — и не только для компаний-разработчиков ПО. В подобных системах хранится не просто код продукта, но и, с учётом развития и преимуществ подхода «всё как код» (Infrastructure as Code, Docs as Code, Security as Code, GitOps и другие практики), в репозиториях описана инфраструктура стендов, систем и приложений — конфигурации облачных сред, интеграции с платёжными системами, ключи к API партнёров и внутренние SDK. По существу, репозиторий стал хранилищем бизнес-активов, доступ к которому нередко регулируется значительно слабее, чем доступ к корпоративным базам данных или файловым серверам.

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

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

Для выявления основных угроз существует много различных фреймворков и методологий: OWASP Threat Modeling Process, DREAD, LINDDUN, PASTA, методические указания ФСТЭК России и другие. Одним из наиболее широко применяемых фреймворков построения моделей угроз является STRIDE — методика, разработанная Microsoft и ставшая де-факто стандартом в отрасли. Название — аббревиатура шести классов угроз: Spoofing (подмена), Tampering (модификация), Repudiation (отрицание), Information Disclosure (раскрытие информации), Denial of Service (отказ в обслуживании), Elevation of Privilege (повышение привилегий).

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

S — Spoofing: подмена идентификатора

В чём угроза. Git по умолчанию не проверяет личность автора коммита: имя и e-mail в истории изменений разработчик указывает сам. Технически любой сотрудник может зафиксировать изменения от имени другого человека. Кроме того, компрометация личного токена доступа (Personal Access Token) или SSH-ключа позволяет злоумышленнику действовать под чужой учётной записью — читать репозитории, вносить изменения, запускать пайплайны.

Конкретные сценарии: утечка токена через буфер обмена, мессенджер, скриншот или случайный коммит в публичный репозиторий; использование чужого SSH-ключа, добавленного на рабочий сервер; коммиты от имени несуществующего или уволенного сотрудника.

Меры защиты:

  • Двухфакторная аутентификация (2FA) обязательна для всех — компрометация пароля недостаточна для входа.
  • Подписание коммитов GPG-ключом — разработчик генерирует GPG-ключ, добавляет публичный ключ в профиль GitLab и подписывает коммиты командой git commit -S. GitLab проверяет подпись и отображает значок «Verified» рядом с каждым коммитом. Если коммит сделан без подписи или с несоответствующей подписью — он помечается как «Unverified». Это не блокирует push автоматически, но создаёт заметную аномалию в истории, видимую при ревью или расследовании.
  • Ротация и аудит токенов и SSH-ключей — скомпрометированный ключ имеет ограниченное окно действия. Регулярно выгружайте список всех активных токенов через Admin → Credentials и отзывайте токены сотрудников, покинувших проект или компанию.
  • Запрет «бессрочных» токенов доступа — снижает риск долгоживущих утечек.
  • Единая точка аутентификации (SSO/LDAP) — отзыв учётной записи в одном месте немедленно закрывает доступ к GitLab.

T — Tampering: несанкционированная модификация

В чём угроза. Репозиторий хранит не только код, но и историю всех изменений — и эту историю можно переписать. Прямая запись в основную ветку в обход проверки, подмена релизного тега, принудительное обновление (force push), изменение конфигурации CI/CD-конвейера — всё это относится к классу модификации.

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

Конкретные сценарии: разработчик с правами Maintainer вносит изменения в продуктивную ветку напрямую, минуя ревью, злоумышленник подменяет тег v2.5.0 так, что он указывает на другой коммит, изменение в .gitlab-ci.yml добавляет шаг, который отправляет артефакты сборки на внешний адрес.

Меры защиты:

  • Protected branches: запрет прямого push в основные ветки — любое изменение идёт через Merge Request с проверкой.
  • Запрет force push даже для Maintainer — история не может быть переписана в обход контроля.
  • Protected tags для основных или релизных веток — релизные теги не могут быть удалены или переназначены.
  • CODEOWNERS на конфигурации CI/CD — изменение пайплайна требует одобрения назначенных владельцев. К примеру, для GitLab принудительное требование апрува от CODEOWNERS — это функция Premium; в Community Edition эквивалентный контроль обеспечивается через CI-задачу, проверяющую апруверов MR по API, или через ограничение «Allowed to merge» только назначенным людям.
  • Обязательная проверка CI-статуса перед слиянием — вредоносный или сломанный пайплайн виден до того, как код попал в main.

R — Repudiation: отрицание действий

В чём угроза. Без надлежащего журналирования невозможно достоверно установить, кто именно и когда выполнил то или иное действие в репозитории: удалил ветку, изменил настройки доступа, запустил пайплайн с привилегированного runner. Это делает расследование инцидентов крайне затруднённым и лишает доказательной базы при разборе нарушений.

Конкретные сценарии: сотрудник отрицает факт пуша вредоносного изменения, ссылаясь на то, что «кто-то использовал его учётную запись»; — нет возможности установить, кто изменил настройки видимости репозитория с private на public; — после инцидента журналы событий GitLab оказываются недоступны или перезаписаны.

Меры защиты:

  • Audit log GitLab с экспортом в SIEM — неизменяемая запись всех административных и пользовательских действий.
  • GPG-подписи коммитов — подписанный коммит является криптографическим доказательством авторства, которое сложно оспорить без компрометации ключа. В GitLab история коммитов с подписями видна публично в интерфейсе и доступна через API для автоматической проверки.
  • Webhooks или интеграция с мессенджером для оповещений о событиях высокого риска — оперативное обнаружение подозрительных действий: изменение visibility проекта, добавление нового пользователя с правами Maintainer/Owner, изменение настроек protected branches, добавление нового deploy key.

I — Information Disclosure: раскрытие информации

В чём угроза. Это наиболее распространённый класс угроз для VCS. Секреты в истории коммитов, форки с избыточными правами, утечки через артефакты CI/CD, доступ к закрытым репозиториям через неправильно настроенные токены — всё это ведёт к раскрытию информации, которая должна оставаться внутри периметра.

Конкретные сценарии: API-ключ, попавший в репозиторий три месяца назад и «удалённый» через коммит, по-прежнему доступен в истории; форк приватного репозитория в личном пространстве сотрудника случайно переводится в режим public; артефакты сборки (docker image, архив с бинарями) доступны без аутентификации через публичный URL.

Меры защиты:

  • Secret scanning на каждом MR и периодический скан истории — обнаружение секретов до и после попадания в репозиторий.
  • Private visibility группы и всех проектов — репозитории недоступны без явного предоставления прав. Для GitLab visibility можно установить на уровне группы: Group Settings → General → Visibility level = Private.
  • Запрет форков за пределы доверенной группы — приватный код не может оказаться в публичном пространстве. Для GitLab: Project Settings → General → Visibility → Forks — установите значение «No one» для критичных проектов или «Only project members» как минимум.
  • Хранение секретов в Vault/CI variables, а не в файлах репозитория — устраняет сам источник угрозы. Все API-токены, пароли, ключи и сертификаты должны храниться в специализированных хранилищах, например HashiCorp Vault, Yandex Lockbox, AWS Secrets Manager, и передаваться приложениям через runtime-переменные окружения.
  • Ограничение доступа к артефактам CI/CD — артефакты сборки недоступны анонимно. По умолчанию артефакты GitLab могут быть доступны без аутентификации, поэтому доступ к ним важно ограничивать отдельно.

D — Denial of Service: отказ в обслуживании

В чём угроза. Репозиторий и CI/CD-инфраструктура могут стать целью атак, направленных на нарушение доступности: перегрузка раннеров (серверов, выполняющих автоматические задачи), засорение репозитория огромными файлами, исчерпание дискового пространства или вычислительных ресурсов GitLab. Для компаний с непрерывным циклом разработки простой CI/CD напрямую влияет на скорость доставки изменений в продукт.

Конкретные сценарии: разработчик случайно добавляет в репозиторий дамп базы данных на 10 ГБ, что исчерпывает дисковую квоту группы; вредоносный пайплайн запускает бесконечный цикл, монополизируя раннеры; внешняя DDoS-атака на инстанс GitLab нарушает работу команды разработки.

Меры защиты:

  • Квоты на размер репозитория и артефактов — защита от случайного или намеренного исчерпания хранилища.
  • Ограничение времени выполнения и параллелизма CI-задач — один пайплайн не монополизирует всю инфраструктуру.
  • Выделенные раннеры для чувствительных проектов — инциденты с раннерами других проектов не затрагивают критичные проекты.
  • Резервное копирование и план восстановления GitLab — возможность быстрого восстановления после деструктивного инцидента.
  • Rate limiting для API и веб-интерфейса — снижение эффективности автоматизированных атак.

E — Elevation of Privilege: повышение привилегий

В чём угроза. Атакующий, получивший минимальный доступ к репозиторию, может попытаться расширить свои полномочия: через уязвимость в пайплайне получить доступ к защищённым секретам CI, через компрометацию аккаунта Maintainer — изменить настройки проекта, или через вредоносный код в зависимостях — получить доступ к продуктивной инфраструктуре.

CI/CD-конвейер в этом контексте особенно уязвим: задача в пайплайне выполняется с определёнными правами в инфраструктуре, и, если эти права избыточны, компрометация пайплайна означает компрометацию всего окружения.

Конкретные сценарии: разработчик с правами Developer создаёт MR с вредоносным шагом в пайплайне, который при выполнении читает защищённые переменные CI; токен деплоя выдан с правами «write» на весь реестр образов, хотя достаточно прав «read» на один репозиторий; компрометация аккаунта с правами Owner позволяет атакующему добавить внешнее зеркало и начать репликацию кода.

Меры защиты:

  • Принцип минимальных привилегий для всех ролей и токенов — компрометация минимального доступа не даёт возможности эскалации. Большинству разработчиков достаточно роли Developer. Maintainer нужен только тем, кто управляет настройками проекта. Owner — единицы: 1–2 технических владельца.
  • Protected variables в CI доступны только protected-веткам — пайплайн из feature-ветки не может прочитать продуктивные секреты. При создании переменной в CI/CD Settings нужно установить флаг «Protected» — переменная будет доступна только в пайплайнах, запущенных из protected-веток или тегов.
  • Регулярный аудит и ротация токенов/ключей развёртывания — своевременное выявление избыточных прав и устаревших учётных данных.
  • Отдельные раннеры с изолированными окружениями — компрометация одного пайплайна не распространяется на соседние проекты.
  • Ограничение числа пользователей Owner/Maintainer — эскалация требует компрометации привилегированного аккаунта, которых мало.

Автор: Мыськив Иван начальник отдела противодействия компьютерным атакам и управления уязвимостями информационных систем Digital Design

Digital Design
Автор: Digital Design
Компания «Диджитал Дизайн» — один из 20 крупнейших разработчиков ПО и лидирующий поставщик BPM-систем в России — оказывает комплексные услуги по автоматизации бизнес-процессов: внедрению систем электронного документооборота, корпоративных порталов, инфраструктурных и мобильных решений, разработке ПО на заказ, импортозамещению и информационной безопасности.
Комментарии: