LIVE

Передача исходного кода: что повышает риск утечки

Передача репозитория подрядчику входит в рутину любого цифрового проекта — и практически всегда проходит через один и тот же набор неубранных окон. Права доступа выдаются «на всякий случай». История Git остаётся полной. Секреты лежат в конфигах.

Обновлено09 ноября 2026 г.
Чтение8 мин
Передача исходного кода: что повышает риск утечки

Форки размножаются бесконтрольно. Каждое из этих окон — отдельный вектор эксплуатации, и каждый из них уже описан в рекомендациях CISA, NIST и OWASP. Проблема не в том, что подрядчики в массе своей враждебны. Проблема в том, что стандартный процесс «отправить архив, выдать токен, дать на GitLab» не закрывает ни один из этих слоёв.

Риски передачи исходного кода — это не абстрактный процент вероятности утечки, а перечень конкретных изъянов в конфигурации и процессах, которые можно эксплуатировать. И почти все эти изъяны находятся не в самой передаче файлов, а в том, что происходит вокруг неё: в правах доступа, истории Git, CI/CD, логах и управлении копиями.

Доступ к репозиторию: права и способ передачи

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

CISA идёт дальше: многофакторная аутентификация должна защищать все виды доступа к защищённым репозиториям, а не только момент отправки изменений. То есть при чтении, при разветвлении, при просмотре — везде. И это важное различие: MFA на пуш изменений не закрывает чтение кода, копирование и разветвление репозитория.

Способ передачи репозитория также имеет значение. Если репозиторий отдан через внутренний SSH-туннель с ключом на машине подрядчика — это один набор рисков. Если архив выгружен в облачное хранилище и за паролем — это другой набор. Если выдан read-only доступ к GitLab с токеном, не ограниченным по времени — третий. Ни один из этих способов не является безопасным сам по себе; вопрос всегда в том, какие права при этом выданы и на какой срок.

Доступ выдаётся на всё, а нужно — на конкретную задачу и на конкретный срок. Остальное — открытая дверь.

Что выдаётся вместе с кодом

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

  • CI/CD-конфигурации — файлы пайплайнов, хранящие секреты, токены и ключи доступа.
  • Переменные окружения — значения, которые могут содержать пароли и API-ключи.
  • Журналы сборок — логи, в которых могут оказаться отпечатки секретов.
  • Образы контейнеров — в Kubernetes, секреты, встроенные в образ, доступны всем, кто получил доступ к образу.

OWASP подчёркивает отдельно: секреты в репозитории могут быть скопированы или перенесены в небезопасные места. Это не гипотетический сценарий — это стандартное поведение инструментов, которые разработчики используют ежедневно.

История Git, форки и копии: где сохраняются секреты

Один из самых распространённых заблуждений при передаче кода: «мы удалили пароль из файла — теперь он чистый». Это не работает. Git хранит полную историю изменений, и удалённый в текущей версии секрет остаётся в предыдущих коммитах. OWASP предупреждает прямо: копии или форки репозитория могут привести к раскрытию секретов, если они попадают в такие копии. Отдельно рекомендуется проверять, что форк или копирование задания не переносит секрет.

Когда репозиторий разветвлён — форк создан в GitHub, скопирован в GitLab, зеркалирован на внутреннем сервере, — история коммитов размножается. Каждая копия несёт в себе полный набор предыдущих версий. Удаление секрета из основной ветки не влияет ни на одну из этих копий.

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

Конкретные следы в истории

Где остаётсяЧто обнаруживаетсяПочему опасно
Предыдущие коммитыПароли, токены, ключи APIДоступно любому с read-доступом
Форки и зеркалаПолная история секретовНе подлежит очистке из основной ветки
Резервные копии репозиторияСнапшоты с секретамиМогут храниться годами
Конфигурации CI/CDТокены и ключи в plaintextДоступно любому с доступом к пайплайну

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

Ключи API, пароли и SSH-данные в CI/CD, логах и командах

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

Консоль и логи

Разработчик запускает скрипт, который печатает переменную окружения в stdout. Лог CI-системы записывает вывод. Лог хранится в архиве. Архив доступен всем, у кого есть доступ к панели CI. Секрет «удалён из репозитория», но он в логах — и логи не очищаются автоматически.

История команд

В истории командного интерпрейса остаются строки вида mysql -u root -p mysecretpassword. OWASP рекомендует не оставлять секреты в истории команд. При передаче рабочей среды подрядчику (виртуальная машина, рабочая станция, docker-образ) история команд передаётся вместе с ней.

Переменные окружения в Kubernetes

OWASP для Kubernetes отмечает отдельно: секреты могут раскрыться через переменные окружения и журналы. Если секрет встроен в контейнерный образ или передан через env, любой, кто получил доступ к поду или образу, получает и секрет. Это не требует эксплойта — достаточно прав на чтение пода.

Секрет — это не файл. Секрет — это всё, где он мог оказаться: в репозитории, в логах, в истории команд, в образе, в переменной окружения.

Проверка изменений и аудит: как обнаруживать рискованные действия

CISA рекомендует не принимать изменения кода в репозиторий без проверки коллегой или руководителем. Рекомендация сопровождается дополнениями: комментарий с соответствующим требованием и тесты. Это стандартный pull request workflow, который описывается как обязательный — не потому что он нов, а потому что без него любой коммит (включая коммит с внедрённым бэкдором или утечкой секрета) попадает в историю без следа аудита.

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

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

1. Действия в CI/CD — запуски пайплайнов, изменение переменных окружения, добавление новых этапов сборки.

2. Создание форков и зеркал — любое разветвление репозитория за пределы основного сервера.

3. Выгрузку артефактов — скачивание собранного кода, архивов, образов.

4. Изменение прав доступа — выдачу новых токенов, создание новых ключей SSH, добавление пользователей.

NIST также указывает: MFA и защищённые протоколы связи названы важными механизмами контроля доступа. Это не замена аудита — это слой, который стоит до аудита. Если аудит обнаружил несанкционированное действие, MFA и протоколы должны были не допустить его. Работают они вместе, а не вместо друг друга.

Смена подрядчика: управление доступами к репозиторию и связанным сервисам

Окончание контракта с подрядчиком — это не только отключение GitLab-аккаунта. Рекомендация OWASP для доступа к секретам в CI/CD включает: ограничить доступ необходимыми для конкретной задачи правами, минимизировать число администраторов, вести журналы и регулярно менять секреты. Ротация секретов — не «по возможности», а регулярная операция, и при смене подрядчика она обязательна.

При увольнении или окончании контракта с подрядчиком перечень действий должен включать:

1. Отключение доступа к репозиторию (все аккаунты, токены, ключи SSH).

2. Ротацию всех токенов и API-ключей, которые выдавались подрядчику.

3. Ротация ключей CI/CD, паролей баз данных и данных аутентификации, к которым подрядчик имел доступ.

4. Проверка форков и зеркал — удаление или отзыв доступа к разветвлённым копиям.

5. Очистка или проверка логов, в которых могли оказаться секреты.

6. Проверка прав доступа к облачным сервисам, хостингу и инфраструктуре.

Пункт 4 — один из самых пропускаемых. Подрядчик мог создать форк на личном GitHub-аккаунте «для удобства». Он мог зеркалить репозиторий на внутреннем сервере клиента. Он мог выгрузить архив в личное облачное хранилище. Ни один из этих действий не отражается в основном репозитории, и ни одно из них не отключается при отзыве доступа к GitLab. Их нужно находить отдельно — через список зеркал, через сканирование форков, через проверку токенов и ключей.

Итоговая таблица рисков и мер

Фактор рискаЧто рекомендуют CISA / NIST / OWASPЧто происходит без меры
Широкие права доступаНаименьшие привилегии, MFA на все виды доступаЧитатель репозитория получает форки и историю
Секреты в репозиторииСканирование, мониторинг, не хранить в кодеКлючи API и пароли в форках и логах
Отсутствие аудитаЖурнал изменений: автор, файлы, датаНевозможно реконструировать действия
Нет проверки измененийPull request с review и тестамиБэкдор или утечка попадает без следа
Неротированные секреты при смене подрядчикаРегулярная ротацияСтарые ключи остаются активными

Что делать

Передача исходного кода подрядчику — это не операция «отправить и забыть». Это процесс, который начинается с прав доступа, заканчивается ротацией секретов и включает между ними аудит, сканирование и контроль копий. CISA, NIST и OWASP сходятся в одном: ни одно из этих действий не заменяет другое. Шифрование канала не закрывает историю Git. VPN не закрывает права доступа. MFA не закрывает логи. Сканирование не закрывает форки. Каждый слой закрывает только свою часть, и удаление любого из них открывает вектор, который существовал и до этого.

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

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

Частые вопросы

Почему удалённый из Git секрет всё ещё может быть доступен?
Git сохраняет историю изменений, поэтому секрет может остаться в предыдущих коммитах, форках, зеркалах и резервных копиях. Удаление из основной ветки не очищает эти копии.
Какие данные могут утечь вместе с репозиторием?
Риск могут представлять CI/CD-конфигурации, переменные окружения, журналы сборок и образы контейнеров. В них могут оказаться токены, ключи доступа, пароли или другие секреты.
Как защитить доступ подрядчика к репозиторию?
Следует выдавать только права, необходимые для конкретной задачи, и ограничивать их срок. MFA рекомендуется для всех видов доступа к защищённому репозиторию, включая чтение и разветвление.
Где секреты могут сохраниться помимо исходного кода?
Они могут попасть в вывод консоли и логи, историю команд, переменные окружения и образы контейнеров. При передаче рабочей среды подрядчику вместе с ней может передаться и история команд.
Что нужно сделать с доступами после окончания работы подрядчика?
Отключить его аккаунты, токены и SSH-ключи, ротировать выданные ему токены, API-ключи и другие доступные секреты. Также нужно отдельно проверить форки и зеркала, логи и права в связанных сервисах.