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

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

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

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

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

Категории

Все категории
Loading categories
inference-gateway-PoC — PoC — межсайтовые запросы повторно используют настроенный API-ключ провайдера в inference-gateway (GHSA-5293-fcm6-fh8v, CVE-2026-87009, CVSS 5.4). | Kitploit
Инструменты/GitHubGitHub/squeeze440/inference-gateway-poc
Анализ уязвимостейЭксплуатацияВеб-безопасностьТестирование на ПроникновениеАутентификацияБезопасность API
GitHubsqueeze440/inference-gateway-poc

inference-gateway-PoC

PoC — межсайтовые запросы повторно используют настроенный API-ключ провайдера в inference-gateway (GHSA-5293-fcm6-fh8v, CVE-2026-87009, CVSS 5.4).

Репозиторий
14 ч 24 мин назадЕщё не проверено

Популярное

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

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

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

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

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

inference-gateway: рекомендации по безопасности

ИсследовательDostxodjayev Abdullox (@squeeze440)
РекомендацияGHSA-5293-fcm6-fh8v
CVECVE-2026-87009
CVSS 3.15.4 (Средний) — CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:L
СлабостьCWE-352, CWE-306, CWE-346
СтатусИсправлено в v0.46.0

Краткое описание: inference-gateway привязывается к 0.0.0.0 и по умолчанию поставляется с отключённой аутентификацией (AUTH_ENABLED=false), а его сквозной маршрут ANY /proxy/:provider/*path безусловно удаляет любой предоставленный вызывающей стороной заголовок Authorization и заменяет его собственным API-ключом провайдера, настроенным на сервере оператора шлюза, перед перенаправлением вверх по потоку, без политики CORS и без какой-либо защиты от CSRF, что позволяет любой веб-странице, которую посещает браузер жертвы, незаметно инициировать оплачиваемые запросы к LLM через собственную учётную запись OpenAI/Anthropic/и т. д. жертвы.

Продукт: inference-gateway/inference-gateway — самостоятельно размещаемый облачно-ориентированный шлюз LLM (Go, Gin).

Протестированная версия: коммит 6677da6afd0a606899f833c2351635edeef386f5 (main, 2026-08-04). Затронуто: <= 0.45.0.

Подробности

Три независимых факта складываются в эту уязвимость.

1. Аутентификация отключена, а привязка по умолчанию публичная. config/config.go:77 — AuthConfig.Enabled по умолчанию имеет значение false. config/config.go:94 — ServerConfig.Host по умолчанию имеет значение 0.0.0.0. При отключённой аутентификации NewOIDCAuthenticatorMiddleware (api/middlewares/auth.go:27-30) возвращает OIDCAuthenticatorNoop, чей Middleware() (api/middlewares/auth.go:48-52) является чистым сквозным пропуском. В этом режиме нет проверки идентичности для каждого запроса ни на одном маршруте. Быстрый старт examples/docker-compose/basic/docker-compose.yml публикует 8080:8080 без установленного AUTH_ENABLED, поэтому документированный путь начала работы приводит именно к такой конфигурации.

2. /proxy/:provider/*path всегда внедряет собственный ключ провайдера оператора. api/routes.go:102-131 (ProxyHandler) вызывает applyProviderAuth, api/routes.go:287-312:

root@kitploit:~
func applyProviderAuth(req *http.Request, provider core.IProvider) error {
	req.Header.Del("Authorization")          // caller's own Authorization header is discarded
	token := provider.GetToken()             // the operator's configured key (env var, e.g. OPENAI_API_KEY)
	switch provider.GetAuthType() {
	case constants.AuthTypeBearer:
		req.Header.Set("Authorization", "Bearer "+token)
	...

Не существует пути в коде, где используется собственный учётный данные вызывающей стороны; дизайн всегда подставляет настроенный ключ шлюза. В сочетании с фактом 1 неаутентифицированный вызывающий получает реальный ключ оператора бесплатно.

3. Ни политики CORS, ни защиты от CSRF не существует нигде в цепочке middleware. cmd/gateway/main.go:271 создаёт роутер с помощью gin.New() (без middleware по умолчанию); цепочка (:273-290) — это otel → logger → telemetry → OIDC auth → guardrails → MCP. go.mod/go.sum не содержат пакета CORS. Заголовок Access-Control-Allow-Origin никогда не отправляется. Обработчику прокси не нужен ни пользовательский заголовок, ни CORS-небезопасный Content-Type для работы (он пересылает необработанное тело, затем перезаписывает исходящий Content-Type на application/json в api/routes.go:254), поэтому «простой» кросс-доменный fetch() (Content-Type: text/plain, без пользовательских заголовков) отправляется браузером без preflight. Серверный оплачиваемый запрос завершается независимо от клиентского применения CORS браузером.

Итоговый эффект: любой источник, который посещает браузер жертвы, пока шлюз доступен из этого браузера (loopback, LAN или публично, если оператор следовал документированному шаблону публикации 8080:8080), может инициировать произвольные выбранные злоумышленником завершения чата через реальную учётную запись провайдера оператора, с нулевой аутентификацией и без какого-либо видимого пользователю признака.

Доказательство концепции

Динамически подтверждено сквозным образом с помощью реального браузера Chrome, выполняющего подлинный кросс-доменный запрос между двумя различными loopback-источниками (шлюз на 127.0.0.1, страница злоумышленника на 127.0.0.2). См. poc/:

  • poc/attacker_site/attack.html — точная страница, отдаваемая с источника злоумышленника; её единственное действие при загрузке — один fetch() к /proxy/openai/chat/completions.
  • poc/mock_upstream.py — заменяет api.openai.com, логирует заголовок Authorization, Origin и тело, которое получает.
  • poc/README.md — полные шаги запуска.

Наблюдалось: кросс-доменный запрос браузера (Origin: http://127.0.0.2:8000) достиг mock-сервера выше по потоку, неся Authorization: Bearer sk-proj-VICTIM-REAL-BILLED-KEY-... и выбранное злоумышленником тело {"messages":[{"role":"user","content":"CSRF-DRIVEBY-MARKER-8271"}]} — страница злоумышленника никогда не обладала, не видела и не запрашивала никаких учётных данных. Проверка сетевого трафика браузера подтвердила, что POST http://127.0.0.1:8081/proxy/openai/chat/completions [200] был инициирован со страницы 127.0.0.2:8000. Полные доказательства, управляемые браузером (сетевой лог, скриншот), приложены к GHSA-5293-fcm6-fh8v.

Влияние

Любой оператор, запускающий inference-gateway с его документированной конфигурацией по умолчанию, позволяет использовать свои настроенные API-ключи провайдера любой веб-странице, доступной браузеру, который может достичь порта шлюза, без учётных данных, cookie или особого сетевого положения, кроме «может отправить HTTP-запрос на адрес шлюза». Конкретно: несанкционированное потребление биллинга/квоты на собственной учётной записи провайдера оператора, слепо инициируемое любым сторонним веб-сайтом, рекламой или скомпрометированной страницей, открытой у оператора (или у любого в той же LAN), пока шлюз работает. Браузер блокирует злоумышленнику чтение вывода модели (нет заголовков CORS), поэтому это слепая принудительная транзакция, а не примитив чтения.

Слабости

  • CWE-352 Cross-Site Request Forgery — дорогостоящее изменяющее состояние действие, выполняемое через кросс-доменный запрос, инициированный браузером, без анти-CSRF токена, без проверки Origin/Sec-Fetch-Site и без ограничения CORS.
  • CWE-306 Missing Authentication for Critical Function — каждый маршрут, кроме /health, имеет нулевую проверку идентичности для каждого запроса, когда AUTH_ENABLED=false, что является документированным значением по умолчанию.
  • CWE-346 Origin Validation Error — ни политики CORS, ни списка разрешённых источников нигде в цепочке middleware.

Исправление

Исправлено в v0.46.0 (сопровождающий ужесточил значения по умолчанию). Рекомендуемые меры:

  1. Требовать пользовательский, не входящий в safelist заголовок на /proxy/:provider/*path (и других изменяющих состояние маршрутах), что вынуждает CORS preflight для кросс-доменных вызывающих и даёт шлюзу место для применения списка разрешённых источников. Это закрывает обход через «простой запрос» без необходимости включать аутентификацию.
  2. Изменить значение по умолчанию SERVER_HOST с 0.0.0.0 на 127.0.0.1, требуя явного согласия на более широкий интерфейс (как сделал Ollama для того же класса уязвимостей).
  3. Выдавать предупреждение при запуске или отказываться запускаться, когда AUTH_ENABLED=false и SERVER_HOST не является loopback.
  4. Документировать риск в README.md / Configurations.md.

Благодарность

Dostxodjayev Abdullox (@squeeze440)

Скачать инструмент