РАЗБОР На проверке 

Критическая уязвимость GitLab: detection и митигация

Сергей Попов
Сергей Попов Red Team · 6,5 тыс. сообщений
Подписаться
64
Режим чтения
Расколотый шестигранный кристалл на чёрном антистатическом коврике, в трещине светится пурпурно-голубой разлом. На уцелевшей грани лазером выгравирована маркировка уязвимости GitLab с кодом CVE.


Понедельник, 9:15 утра. В Wazuh прилетает алерт: серия неаутентифицированных POST-запросов на /api/graphql с нестандартной директивой @gl_introduced на self-managed GitLab-инстансе за nginx. За два дня до этого WatchTowr воспроизвели CVE-2026-19478 за минуты - хватило advisory и патч-diff. А через месяц CISA добавит CVE-2026-85706 в KEV-каталог с дедлайном патча в трое суток. За лето-осень 2026 года GitLab закрыла четыре критических и высоких CVE в двух внеочередных патч-релизах - три unauthenticated (CVE-2026-85706 с CVSS 10.0, CVE-2026-19478 с CVSS 9.4, CVE-2026-19650 с CVSS 7.1) и одну authenticated (CVE-2026-87719, CVSS 9.9, только EE). Помимо этих четырёх, релизы закрывали дополнительные уязвимости без CVE-идентификаторов - полный перечень в official security advisories GitLab. Ниже - разбор каждого вектора, конкретные detection-правила и пошаговая митигация.

Хронология: четыре критических CVE и два патч-релиза GitLab​

Два внеочередных патч-релиза - за рамками планового цикла обновлений - прямо указывают на уровень угрозы. GitLab обычно копит фиксы до регулярного цикла, а экстренный патч означает одно: кто-то уже ломает или вот-вот начнёт. Подробнее - в нашем статье о appsec в devsecops.

Волна 1 - 17 августа 2026. Патч-версии 19.2.4, 19.1.6, 19.0.8, 18.11.11. Закрыты CVE-2026-19478 (CVSS 9.4, Critical, CWE-94) и CVE-2026-19650 (CVSS 7.1, High, CWE-352). Обе затрагивают GraphQL API в CE и EE для версий от 18.2 до соответствующих фиксов. 18 августа WatchTowr подтвердили воспроизводимость CVE-2026-19478, 20 августа - первые exploitation attempts в honeypot-сети (по данным SecurityWeek).

Волна 2 - сентябрь 2026. Патч-версии 19.3.2, 19.2.6, 19.1.8. Закрыты CVE-2026-85706 (CVSS 10.0, Critical, CWE-22) и CVE-2026-87719 (CVSS 9.9, Critical, CWE-502). CVE-2026-85706 - path traversal в repository commits API, добавлена в CISA KEV 11 сентября с дедлайном 14 сентября. Сканирование уязвимых серверов зафиксировано с 11 сентября, эксплуатация - через считанные часы после раскрытия (по данным Xakep.ru).

Ранее, в начале 2026 года, GitLab также выпускала патчи для CVE-2026-0723 (обход 2FA, CVSS 7.4, CWE-252) и нескольких DoS-уязвимостей (CVE-2025-13927, CVE-2025-13928, CVE-2026-1102). Закрыты в версиях 18.8.2, 18.7.2 и 18.6.4.

EPSS-данные на 18 сентября 2026: CVE-2026-85706 - 0.1456 (percentile 96.48, Top 5%), CVE-2026-19478 - 0.0581 (percentile 92.79, Top 10%). Обе в зоне повышенного риска автоматизированной эксплуатации. CVE-2026-87719 и CVE-2026-19650 ниже медианы EPSS (percentile 47.91 и 40.06), но EPSS оценивает вероятность, а не последствия - а последствия при успешной атаке критичны.

По классификации MITRE ATT&CK все три unauthenticated CVE - это Exploit Public-Facing Application (T1190, Initial Access). При успешной эксплуатации атакующий добирается до Code Repositories (T1213.003, Collection) и дальше - к Compromise Software Dependencies and Development Tools (T1195.001, Initial Access) для supply chain-атак.

CVE-2026-85706 - эксплуатация уязвимости GitLab с CVSS 10.0​

Приоритет номер один. CISA-ADP присвоила решение Act (патчить немедленно): Exploitation - active, Automatable - yes, Technical Impact - total. Добавлена в KEV-каталог 11 сентября 2026 с трёхдневным дедлайном по BOD 26-04.

Механизм. Некорректное ограничение путей (CWE-22) плюс отсутствие проверки аутентификации в repository commits API. Неаутентифицированный атакующий шлёт запрос к /api/v4/projects/{id}/repository/commits/ с параметром file.path, содержащим traversal payload (../), и читает произвольные файлы на сервере GitLab. Достаточно одного публичного проекта на инстансе.

CVSS-вектор: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N. Ключевое - S:C (Changed Scope): атакующий выходит за пределы уязвимого компонента. C:H/I:H - полная компрометация конфиденциальности и целостности. На практике утекают: конфигурация GitLab (/etc/gitlab/gitlab.rb, /var/opt/gitlab/), Rails secrets (gitlab-secrets.json), CI/CD runner tokens, интеграционные секреты (Vault, AWS, K8s service accounts).

Затронутые версии: CE/EE 18.7 - 19.1.7, 19.2 - 19.2.5, 19.3 - 19.3.1. Исправлено в 19.3.2, 19.2.6, 19.1.8.

PoC и автоматизация. На GitHub минимум шесть репозиториев с PoC-эксплойтами (guneykabel/cve-2026-85706 с 38 звёздами, mhtsec/CVE-2026-85706, plur1bu5/gitread и другие). Nuclei-темплейт CVE-2026-85706.yaml уже в основном репозитории ProjectDiscovery - автоматизированное сканирование через nuclei -t cves/2026/CVE-2026-85706.yaml доступно любому. Порог входа - нулевой.

Бизнес-логика атаки. Зачем атакующему path traversal в GitLab? Получив конфигурационные файлы с секретами, он переходит к Valid Accounts (T1078, Persistence/Privilege Escalation) - использует утёкшие токены для аутентификации в GitLab, CI/CD-раннерах и downstream-интеграциях. Unauthenticated file read превращается в полноценную supply chain-компрометацию. Один GET-запрос с ../ - и через час атакующий деплоит свой код в production через штатный пайплайн.

CVE-2026-19478 - unauthenticated access через GraphQL-директиву​

NVD классифицирует как CWE-94 (Code Injection), но фактический механизм - не инъекция исполняемого кода в классическом понимании. Уязвимость связана с некорректной валидацией GraphQL-директив (конструкции вида @include, @skip или серверные директивы типа @gl_introduced). Манипуляция директивой позволяет обойти проверки авторизации и выполнить мутации над публичными ресурсами от имени анонимного пользователя. По сути - обход контроля доступа, замаскированный под code injection.

CVSS-вектор: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:H. PR:N/UI:N - ни привилегий, ни действий жертвы. Основной удар - на целостность (I:H) и доступность (A:H): удаление репозиториев, изменение состояния проектов, подделка merge-записей, бан мейнтейнеров.

Supply chain-импакт - вот где становится по-настоящему неприятно. По словам Mondoo CSO Patrick Münch (через SecurityWeek), атакующий может подделать merge-запись так, что вредоносное изменение выглядит проверенным и подписанным доверенным разработчиком. Пайплайн собирает и деплоит скомпрометированный артефакт, а аудит-лог подтверждает легитимность процесса. Это Compromise Software Dependencies and Development Tools (T1195.001): атака становится видимой только когда скомпрометированный релиз уже в production.

Хронология. Патч - 17 августа. Воспроизведение WatchTowr - 18 августа. Honeypot-детекция - 20 августа (по данным SecurityWeek и Field Effect). При этом CISA-ADP формально классифицирует exploitation как none и присваивает Track, а не Act - ADP фиксирует подтверждённые инциденты, а не honeypot-активность. Разница между «никто не ломает» и «мы пока не видели подтверждённых жертв» - существенная.

PoC: три публичных репозитория на GitHub, Nuclei-темплейт CVE-2026-19478.yaml доступен.

CVE-2026-87719 и CVE-2026-19650 - insider-угрозы и скомпрометированные сессии​

CVE-2026-87719 (CVSS 9.9, Critical, CWE-502 - Deserialization of Untrusted Data) затрагивает только GitLab Enterprise Edition. Аутентифицированный пользователь с доступом к Duo Chat через специально сформированный аргумент GraphQL subscription обходит механизм сериализации и выполняет server object lookup - получая конфигурацию Advanced Search и учётные данные. Вектор CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H - Changed Scope, полная компрометация CIA-триады. Версии EE от 18.3 до 19.3.1.

Эта уязвимость особенно опасна в цепочке: если через CVE-2026-85706 атакующий утянул токены - он аутентифицируется и использует CVE-2026-87719 для дальнейшей латеральной эскалации. Два CVE - одна атака.

CVE-2026-19650 (CVSS 7.1, High, CWE-352 - CSRF) позволяет выполнять GraphQL-мутации через GET-запросы из-за некорректной валидации multiplex-запросов. Отличие от CVE-2026-19478 - UI:R: нужна жертва с активной сессией, перешедшая по вредоносной ссылке. GET-запросы обходят стандартные CSRF-защиты, так как HTTP-спецификация считает их «безопасными» (ну да, конечно). Сценарий - social engineering против разработчика с активной GitLab-сессией: кидаешь ссылку в Slack, жертва кликает, мутация выполняется от её имени.

Detection: правила корреляции для безопасности CI/CD конвейера​

CVE-2026-85706 - path traversal​

Искать POST-запросы к /api/v4/projects/{id}/repository/commits/ с параметром file.path, содержащим ../. Принципиальный момент: простой счётчик запросов по URL-паттерну /repository/commits/ детектирует только reconnaissance (Vulnerability Scanning, T1595.002). Для обнаружения traversal payload нужен WAF или reverse proxy с логированием тела запроса - ../ находится в параметрах, а не в URL. Без логирования body вы увидите только «кто-то стучался», но не «кто-то уже читает ваш gitlab-secrets.json».

Конфигурация nginx для аудит-логирования тела POST к commits API:
NGINX:
log_format commits_audit '$remote_addr [$time_local] "$request" '
                         '$status $request_body';
location ~ ^/api/v4/projects/.*/repository/commits {
    access_log /var/log/gitlab/commits_api_audit.log commits_audit;
    client_body_buffer_size 16k;
    proxy_pass http://gitlab-workhorse;
}

CVE-2026-19478 - GraphQL abuse​

По данным WatchTowr (через SecurityWeek), ключевой IoC - строка @gl_introduced в запросах к /api/graphql. Sigma-правило для корреляции:
YAML:
title: GitLab GraphQL directive abuse (CVE-2026-19478)
logsource:
  product: gitlab
  service: api
detection:
  selection:
    cs-uri-stem|contains: '/api/graphql'
    cs-method: 'POST'
  keywords|contains:
    - '@gl_introduced'
  condition: selection and keywords
level: critical
В production_json.log GitLab фиксирует поле meta.user. Пустое значение при мутации (не query) на публичном проекте - аномалия, которая должна триггерить алерт. Анонимный пользователь выполняет мутацию - это не нормальное поведение, это атака.

MITRE ATT&CK detection mapping​

ТехникаТактикаЧто искать в логах
Exploit Public-Facing Application (T1190)Initial AccessPOST на /api/graphql с @gl_introduced; POST на /api/v4/.../commits с ../ в теле
Vulnerability Scanning (T1595.002)ReconnaissanceМассовые GET/HEAD на /api/v4/projects с перебором ID; Nuclei User-Agent
Code Repositories (T1213.003)CollectionЧтение файлов за пределами репозитория через commits API
Compromise Software Dependencies (T1195.001)Initial AccessMerge/commit без соответствующего MR в GitLab UI
Valid Accounts (T1078)PersistenceАутентификация с токенами, которые не выдавались через штатный flow

Исправление уязвимости GitLab: пошаговый чек-лист​

📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме

для замедления reconnaissance. Подписаться на GitLab security advisory: https://about.gitlab.com/security-notices/. Интегрировать проверку версий GitLab в pipeline патч-менеджмента (Renovate для Helm charts).

Регуляторный контекст. CISA BOD 26-04 установил трёхдневный дедлайн для CVE-2026-85706 - критически короткий срок даже для зрелых организаций. По OWASP Top 10 (2021) описанные уязвимости покрывают A03 (Injection), A06 (Vulnerable and Outdated Components), A08 (Software and Data Integrity Failures) для десериализации в CVE-2026-87719 и A09 (Security Logging and Monitoring Failures). Если ваш SIEM не алертит на описанные паттерны - о компрометации вы узнаете из новостей.

За последний год я разбирал три инцидента с self-managed GitLab, где unauthenticated access приводил к компрометации CI/CD. Во всех трёх случаях патч-менеджмент существовал - проблема была в том, что GitLab не попадал в scope «критичных систем» для экстренного патчинга. Его классифицировали как «внутренний инструмент разработки», а не как инфраструктуру с прямым доступом к production secrets. CVE-2026-85706 с CVSS 10.0 и трёхдневным дедлайном CISA KEV - повод пересмотреть эту классификацию раз и навсегда. GitLab-инстанс, доступный из интернета с публичными проектами, - это attack surface уровня production API, а не «девелоперский тул». Detection-правила для него должны стоять на одном уровне с основным веб-приложением. Кто-то из коллег, возможно, возразит, что большинство self-managed инстансов - internal only. По документам - да, на практике - VPN, third-party integrations и developer workstations делают их доступными из куда большего количества точек, чем показывает сетевая схема. Если в вашей инфраструктуре GitLab стоит за нестандартным стеком (Kubernetes, Cloudflare, кастомный WAF) - на codeby.net ведётся тред с разбором detection-подходов под разные варианты деплоя DevOps-платформ.
Полезно

Комментарии

0

Ещё по теме