Проблема
GitLab, GitHub Enterprise, CI runners и package registries давно стали частью Tier-0. Через них проходят исходники, deploy keys, tokens, container images и история изменений.
Поэтому критический баг в такой платформе нельзя закрывать формулой patch applied. Нужно доказать, что до патча не было чтения чувствительных файлов, доступа к секретам, подозрительных pipeline-запусков и новых токенов.
Что проверить
- Версию GitLab и наличие всех security releases на self-managed инстансе.
- Access logs и audit events за окно до обновления.
- Создание deploy tokens, personal access tokens, runners, webhooks и integrations.
- Pipeline variables, masked secrets, protected branches и registry credentials.
- Необычные обращения к API, repository archives, raw files и commits endpoints.
Решение
Правильный response: upgrade, freeze sensitive admin changes, собрать evidence, провести scoped rotation, проверить runners, затем открыть change window обратно.
Для бизнеса важно объяснить не CVSS, а blast radius: какие проекты могли быть затронуты, какие секреты там жили и какие релизы собирались через эту цепочку.
Defensive-чеклист
- Обновить до исправленной версии и зафиксировать digest/версию.
- Сохранить журналы до ротации, чтобы не потерять forensic context.
- Ротировать секреты по приоритету: production deploy, cloud, registry, signing, then lower-tier.
- Проверить CI runners на неизвестные jobs и новые registration tokens.
- Добавить KEV-политику: DevSecOps-система = emergency class, а не ordinary web app.
Безопасный пример
# пример безопасной инвентаризации GitLab audit JSONL без вывода секретов
import json
from collections import Counter
events = Counter()
with open("gitlab-audit.jsonl", encoding="utf-8") as fh:
for line in fh:
row = json.loads(line)
action = row.get("action", "unknown")
target = row.get("target_type", "unknown")
events[(action, target)] += 1
for (action, target), count in events.most_common(20):
print(f"{count:5} {action:32} {target}")