Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
inference-gateway-PoC — PoC — les requêtes cross-origin réutilisent la clé API du fournisseur configurée dans inference-gateway (GHSA-5293-fcm6-fh8v, CVE-2026-87009, CVSS 5.4). | Kitploit
Outils/GitHubGitHub/squeeze440/inference-gateway-poc
Analyse des VulnérabilitésExploitationSécurité WebTests d'IntrusionAuthentificationSécurité des API
GitHubsqueeze440/inference-gateway-poc

inference-gateway-PoC

PoC — les requêtes cross-origin réutilisent la clé API du fournisseur configurée dans inference-gateway (GHSA-5293-fcm6-fh8v, CVE-2026-87009, CVSS 5.4).

Voir le dépôt
il y a 14h 24mPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

inference-gateway : avis de sécurité

ChercheurDostxodjayev Abdullox (@squeeze440)
AvisGHSA-5293-fcm6-fh8v
CVECVE-2026-87009
CVSS 3.15.4 (Moyen) — CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:L
FaiblesseCWE-352, CWE-306, CWE-346
StatutCorrigé dans v0.46.0

Résumé : inference-gateway s'attache à 0.0.0.0 et est livré avec l'authentification désactivée (AUTH_ENABLED=false) par défaut, et sa route de passthrough ANY /proxy/:provider/*path supprime inconditionnellement tout en-tête Authorization fourni par l'appelant et le remplace par la propre clé API du fournisseur configurée côté serveur par l'opérateur de la passerelle avant de transmettre en amont, sans aucune politique CORS et sans aucune protection CSRF, permettant à n'importe quelle page web visitée par le navigateur d'une victime de déclencher silencieusement des requêtes LLM facturées via le propre compte OpenAI/Anthropic/etc. de la victime.

Produit : inference-gateway/inference-gateway — passerelle LLM auto-hébergée, cloud-native (Go, Gin).

Version testée : commit 6677da6afd0a606899f833c2351635edeef386f5 (main, 2026-08-04). Affecté : <= 0.45.0.

Détails

Trois faits indépendants se combinent pour former la vulnérabilité.

1. L'authentification est désactivée et l'attachement est public par défaut. config/config.go:77 — AuthConfig.Enabled vaut false par défaut. config/config.go:94 — ServerConfig.Host vaut 0.0.0.0 par défaut. Avec l'authentification désactivée, NewOIDCAuthenticatorMiddleware (api/middlewares/auth.go:27-30) renvoie OIDCAuthenticatorNoop, dont Middleware() (api/middlewares/auth.go:48-52) est un pur passthrough. Il n'y a aucune vérification d'identité par requête sur aucune route dans ce mode. Le quickstart examples/docker-compose/basic/docker-compose.yml publie 8080:8080 sans AUTH_ENABLED défini, donc le parcours de démarrage documenté produit exactement cette configuration.

2. /proxy/:provider/*path injecte toujours la propre clé du fournisseur de l'opérateur. api/routes.go:102-131 (ProxyHandler) appelle 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)
	...

Il n'existe aucun chemin de code où les propres identifiants de l'appelant sont utilisés ; la conception substitue toujours la clé configurée de la passerelle. Combiné au fait 1, un appelant non authentifié obtient gratuitement la vraie clé de l'opérateur attachée.

3. Aucune politique CORS et aucune protection CSRF n'existent nulle part dans la chaîne de middlewares. cmd/gateway/main.go:271 construit le routeur avec gin.New() (aucun middleware par défaut) ; la chaîne (:273-290) est otel → logger → telemetry → OIDC auth → guardrails → MCP. go.mod/go.sum ne contiennent aucun paquet CORS. Aucun en-tête Access-Control-Allow-Origin n'est jamais envoyé. Le gestionnaire de proxy n'a besoin d'aucun en-tête personnalisé ni d'un Content-Type non sécurisé pour CORS pour fonctionner (il transmet le corps brut, puis écrase le Content-Type sortant en application/json à api/routes.go:254), donc un fetch() cross-origin « simple » (Content-Type: text/plain, aucun en-tête personnalisé) est envoyé par le navigateur sans preflight. La requête facturée côté serveur s'accomplit indépendamment de l'application CORS côté lecture du navigateur.

Effet net : n'importe quelle origine visitée par le navigateur d'une victime, tant que la passerelle est joignable depuis ce navigateur (loopback, LAN, ou public si l'opérateur a suivi le modèle de publication documenté 8080:8080), peut déclencher des complétions de chat arbitraires choisies par l'attaquant via le vrai compte fournisseur de l'opérateur, sans aucune authentification et sans aucune indication visible pour l'utilisateur.

Preuve de concept

Confirmé dynamiquement de bout en bout avec un vrai navigateur Chrome effectuant une véritable requête cross-origin entre deux origines loopback distinctes (passerelle sur 127.0.0.1, page attaquante sur 127.0.0.2). Voir poc/ :

  • poc/attacker_site/attack.html — la page exacte servie depuis l'origine attaquante ; sa seule action au chargement est un fetch() vers /proxy/openai/chat/completions.
  • poc/mock_upstream.py — remplace api.openai.com, journalise l'en-tête Authorization, l'Origin et le corps qu'il reçoit.
  • poc/README.md — étapes d'exécution complètes.

Observé : la requête cross-origin du navigateur (Origin: http://127.0.0.2:8000) a atteint le mock upstream en portant Authorization: Bearer sk-proj-VICTIM-REAL-BILLED-KEY-... et le corps choisi par l'attaquant {"messages":[{"role":"user","content":"CSRF-DRIVEBY-MARKER-8271"}]} — la page attaquante n'ayant jamais possédé, vu, ou demandé aucun identifiant. L'inspection réseau du navigateur a confirmé que POST http://127.0.0.1:8081/proxy/openai/chat/completions [200] a été déclenché depuis la page 127.0.0.2:8000. Les preuves complètes pilotées par navigateur (journal réseau, capture d'écran) sont jointes à GHSA-5293-fcm6-fh8v.

Impact

Tout opérateur exécutant inference-gateway avec sa configuration par défaut documentée voit sa ou ses clés API de fournisseur configurées utilisables par n'importe quelle page web joignable depuis un navigateur pouvant atteindre le port de la passerelle, sans identifiant, cookie, ou position réseau particulière au-delà de « pouvoir envoyer une requête HTTP à l'adresse de la passerelle ». Concrètement : consommation de facturation/quota non autorisée sur le propre compte fournisseur de l'opérateur, déclenchée aveuglément par n'importe quel site tiers, publicité, ou page compromise que l'opérateur (ou quiconque sur le même LAN) a ouverte pendant que la passerelle est en cours d'exécution. Le navigateur empêche l'attaquant de lire la sortie du modèle (aucun en-tête CORS), il s'agit donc d'une transaction forcée aveugle, et non d'une primitive de lecture.

Faiblesses

  • CWE-352 Cross-Site Request Forgery — une action coûteuse modifiant l'état effectuée via une requête cross-origin émise par le navigateur sans jeton anti-CSRF, sans vérification Origin/Sec-Fetch-Site, et sans restriction CORS.
  • CWE-306 Authentification manquante pour une fonction critique — chaque route sauf /health a zéro vérification d'identité par requête lorsque AUTH_ENABLED=false, la valeur par défaut documentée.
  • CWE-346 Erreur de validation d'origine — aucune politique CORS ni liste d'autorisation d'origines nulle part dans la chaîne de middlewares.

Remédiation

Corrigé dans v0.46.0 (le mainteneur a durci les valeurs par défaut). Mesures recommandées :

  1. Exiger un en-tête personnalisé non safelisté sur /proxy/:provider/*path (et les autres routes modifiant l'état), ce qui force un preflight CORS pour les appelants cross-origin et donne à la passerelle un endroit pour appliquer une liste d'autorisation d'origines. Cela ferme le contournement par « requête simple » sans exiger l'activation de l'authentification.
  2. Changer la valeur par défaut de SERVER_HOST de 0.0.0.0 à 127.0.0.1, exigeant un opt-in explicite pour une interface plus large (comme Ollama l'a fait pour la même classe de vulnérabilité).
  3. Émettre un avertissement au démarrage, ou refuser de démarrer, lorsque AUTH_ENABLED=false et que SERVER_HOST n'est pas loopback.
  4. Documenter le risque dans README.md / Configurations.md.

Crédit

Dostxodjayev Abdullox (@squeeze440)

Télécharger l’outil