Joan eduki nagusira
WebguneWebgunebeta
Tarifak
Toutes les failles

MoyenneCVE-2026-1166852026(e)ko urriaren 27(a)

SDK Python du Model Context Protocol : les transports de client HTTP suivaient les redirections cross-origin avec des en-têtes et corps personnalisés

Exploitable dans des cas précis ou avec un impact limité : à corriger à la prochaine mise à jour.

Sévérité
Moyenne5.9 / 10
Publiée le
2026(e)ko urriaren 27(a)
Mise à jour
2026(e)ko urriaren 27(a)

L'avis

Traduction automatique de l'avis officiel. En cas de doute, l'avis d'origine, plus bas, fait foi.

Résumé

Dans les versions affectées, les transports de client Streamable HTTP et SSE du SDK suivaient les redirections HTTP vers n'importe quel hôte. Si le point de terminaison MCP configuré répondait par une redirection vers une origine différente :

  • les en-têtes personnalisés définis sur le client (par exemple une identifiante X-API-Key) étaient envoyés à cette origine, et
  • sur une redirection 307 ou 308, le corps de la demande était également réenvoyé là-bas.

Les fournisseurs de clients OAuth du SDK suivaient les redirections lors de leurs propres demandes de découverte, d'enregistrement et de jeton de la même manière.

Un en-tête Authorization bearer isolé n'était pas exposé ; la bibliothèque HTTP le supprime déjà sur les redirections cross-origin.

Quiconque capable de faire rediriger un point de terminaison que vous faites confiance vers un autre endroit (une redirection obsolète vers un domaine expiré, une règle de proxy mal acheminée, une logique de redirection que l'attaquant peut influencer) pourrait capturer ce matériau. Un serveur qui est lui-même malveillant n'en tire aucun avantage de cette manière ; il reçoit déjà directement vos demandes.

Suis-je concerné ?

Oui, si votre code utilise le SDK en tant que client MCP via HTTP à travers l'une des :

  • streamable_http_client (sur 2.x également Client avec une URL http:// ou https://)
  • streamablehttp_client ou sse_client
  • ClientSessionGroup avec des paramètres de serveur HTTP
  • l'interne create_mcp_http_client d'aide

Cela inclut un client HTTP que vous avez fourni vous-même avec follow_redirects=True.

Versions affectées : 1.8.0 à 1.29.1, et 2.0.0 à 2.1.1.

Non concernés :

  • serveurs MCP
  • clients stdio
  • un client que vous avez fourni avec follow_redirects laissé à sa valeur par défaut de False
Correction

Mettez à niveau vers mcp 1.30.0 (1.x) ou 2.2.0 (2.x) ou ultérieur ; aucun changement de code n'est nécessaire.

Les transports, ainsi que les propres demandes des fournisseurs OAuth, suivent désormais une redirection uniquement lorsqu'elle reste sur l'origine du point de terminaison (même schéma, hôte et port, ou une mise à niveau http vers https sur le même hôte) et conserve la méthode de demande. Toute autre redirection n'est pas suivie et la demande échoue avec une erreur désignant la cible (MCPError sur 2.x, httpx.HTTPStatusError sur 1.x), quel que soit le client HTTP utilisé par le transport. L'interne create_mcp_http_client d'aide ne active plus le suivi de redirection, donc le code l'appelant directement reçoit désormais la réponse de redirection à la place.

Si votre client atteint actuellement son serveur par le biais d'une redirection vers un autre hôte, y compris un serveur qui n'a pas besoin d'identifiants, il arrêtera de se connecter après la mise à niveau : définissez l'URL du point de terminaison sur la cible de la redirection.

Jusqu'à ce que vous puissiez mettre à niveau, fournissez votre propre client HTTP avec follow_redirects laissé à False (http_client= sur streamable_http_client ; httpx_client_factory= sur sse_client et streamablehttp_client ; ClientSessionGroup n'a pas un tel paramètre). Si un client a déjà pu suivre une redirection vers un hôte que vous ne contrôlez pas, faites tourner les identifiants qu'il portait.

<details> <summary>Si vous avez vraiment besoin du comportement ancien (non supporté)</summary>

Ceci restaure ce que cette corrige : les redirections vers n'importe quel hôte sont de nouveau suivies, emportant vos en-têtes personnalisés et, sur 307/308, le corps de la demande, demandes de jeton OAuth incluses. Privilégiez le fait de définir l'URL du point de terminaison sur la cible de la redirection. Si vous ne pouvez pas, et que vous acceptez de transmettre les identifiants vers la cible de la redirection, donnez au transport un client HTTP qui suit les redirections indépendamment de ce que le SDK demande :

import httpx2  # sur 1.x : import httpx et héritez de httpx.AsyncClient à la place

class FollowRedirectsAnyway(httpx2.AsyncClient):
    """Suit les redirections vers N'IMPORT quelle origine. Abandonne délibérément la protection de même origine du SDK."""

    async def send(self, request, *, follow_redirects=False, **kwargs):
        return await super().send(request, follow_redirects=True, **kwargs)

http_client = FollowRedirectsAnyway(timeout=httpx2.Timeout(30, read=300))
# streamable_http_client(url, http_client=http_client)

# sse_client / streamablehttp_client prennent une usine à la place :
def client_factory(headers=None, timeout=None, auth=None):
    return FollowRedirectsAnyway(headers=headers, auth=auth,
                                 timeout=timeout if timeout is not None else httpx2.Timeout(30, read=300))
# sse_client(url, httpx_client_factory=client_factory)

La gestion des redirections est alors celle de la bibliothèque HTTP, comme avant la correction : un en-tête Authorization isolé est toujours supprimé sur les sauts cross-origin et 301/302/303 deviennent GET. Ce n'est pas quelque chose que le SDK supporte ou testes.

</details>

Composants touchés

ComposantVersions touchéesCorrigé en
mcpPython (pip)>= 2.0.0, < 2.2.02.2.0
mcpPython (pip)>= 1.8.0, < 1.30.01.30.0

Vous utilisez une version touchée ? Passez à la version corrigée, puis redéployez.

Model Context Protocol Python SDK: HTTP client transports followed cross-origin redirects carrying custom headers and bodies

Summary

In affected versions, the SDK's Streamable HTTP and SSE client transports followed HTTP redirects to any host. If the configured MCP endpoint answered with a redirect to a different origin:

  • custom headers set on the client (for example an X-API-Key credential) were sent to that origin, and
  • on a 307 or 308 redirect the request body was re-sent there too.

The SDK's OAuth client providers followed redirects on their own discovery, registration and token requests in the same way.

A lone Authorization bearer header was not exposed; the HTTP library already drops it on cross-origin redirects.

Anyone able to make an endpoint you trust redirect elsewhere (a stale redirect to a lapsed domain, a misrouted proxy rule, redirect logic an attacker can influence) could capture that material. A server that is itself malicious gains nothing this way; it already receives your requests directly.

Am I affected?

Yes, if your code uses the SDK as an MCP client over HTTP through any of:

  • streamable_http_client (on 2.x also Client given an http:// or https:// URL)
  • streamablehttp_client or sse_client
  • ClientSessionGroup with HTTP server parameters
  • the internal create_mcp_http_client helper

This includes an HTTP client you passed in yourself with follow_redirects=True.

Affected versions: 1.8.0 through 1.29.1, and 2.0.0 through 2.1.1.

Not affected:

  • MCP servers
  • stdio clients
  • a client you supplied with follow_redirects left at its default of False
Fix

Upgrade to mcp 1.30.0 (1.x) or 2.2.0 (2.x) or later; no code changes are needed.

The transports, and the OAuth providers' own requests, now follow a redirect only when it stays on the endpoint's origin (same scheme, host and port, or an http to https upgrade on the same host) and keeps the request method. Any other redirect is not followed and the request fails with an error naming the target (MCPError on 2.x, httpx.HTTPStatusError on 1.x), whichever HTTP client the transport uses. The internal create_mcp_http_client helper no longer turns redirect following on, so code calling it directly now receives the redirect response instead.

If your client currently reaches its server through a redirect to another host, including a server that needs no credentials, it will stop connecting after the upgrade: set the endpoint URL to the redirect's target.

Until you can upgrade, supply your own HTTP client with follow_redirects left at False (http_client= on streamable_http_client; httpx_client_factory= on sse_client and streamablehttp_client; ClientSessionGroup has no such parameter). If a client may already have followed a redirect to a host you do not control, rotate the credentials it carried.

<details> <summary>If you genuinely need the old behaviour (unsupported)</summary>

This restores what this advisory fixes: redirects to any host are followed again, carrying your custom headers and, on 307/308, the request body, OAuth token requests included. Prefer setting the endpoint URL to the redirect's target. If you cannot, and you accept forwarding credentials to the redirect target, give the transport an HTTP client that follows redirects regardless of what the SDK asks for:

import httpx2  # on 1.x: import httpx and subclass httpx.AsyncClient instead

class FollowRedirectsAnyway(httpx2.AsyncClient):
    """Follows redirects to ANY origin. Deliberately gives up the SDK's same-origin protection."""

    async def send(self, request, *, follow_redirects=False, **kwargs):
        return await super().send(request, follow_redirects=True, **kwargs)

http_client = FollowRedirectsAnyway(timeout=httpx2.Timeout(30, read=300))
# streamable_http_client(url, http_client=http_client)

# sse_client / streamablehttp_client take a factory instead:
def client_factory(headers=None, timeout=None, auth=None):
    return FollowRedirectsAnyway(headers=headers, auth=auth,
                                 timeout=timeout if timeout is not None else httpx2.Timeout(30, read=300))
# sse_client(url, httpx_client_factory=client_factory)

The redirect handling is then the HTTP library's own, as before the fix: a lone Authorization header is still dropped on cross-origin hops and 301/302/303 become GET. It is not something the SDK supports or tests.

</details>

Catégorie : Exposure of Sensitive Information to an Unauthorized Actor (CWE-200)

Vecteur CVSS : CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N

  • github.comhttps://github.com/modelcontextprotocol/python-sdk/security/advisories/GHSA-5h93-6whr-6q8j
  • github.comhttps://github.com/modelcontextprotocol/python-sdk/pull/3397
  • github.comhttps://github.com/modelcontextprotocol/python-sdk/pull/3448
  • github.comhttps://github.com/modelcontextprotocol/python-sdk/commit/2106335745563b2321b8c73fef2c12903d00aa6e
  • github.comhttps://github.com/modelcontextprotocol/python-sdk/commit/c6762e821c527925f0b617db216d00fbd1d0bf99
  • github.comhttps://github.com/modelcontextprotocol/python-sdk/releases/tag/v1.30.0
  • github.comhttps://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.2.0
  • github.comhttps://github.com/advisories/GHSA-5h93-6whr-6q8j
WebguneWebgune

Hodei burujabe osoa, Frantzian diseinatua eta ostatatua.

DiscordDiscordGitHubGitHub
+33 (0)9 72 23 25 00support@webgune.cloud

Produktua

  • Ezaugarriak
  • Tarifak
  • Konparaketa
  • Changelog
  • Egoera
  • Ahuleziak (CVE)
  • Harremanetarako

Garatzaileak

  • Dokumentazioa
  • Frameworkak
  • API erreferentzia
  • Adibideak
  • CLI
  • Tresnak & VS Code

Legala

  • Erabilera baldintzak
  • Pribatutasun politika
  • Ohar legalak
  • Irisgarritasuna
  • RGPD
  • DPA
  • Erabilera onargarriaren politika

© 2026 KX712. Eskubide guztiak erreserbatuta. Webgune KX712-ren zerbitzu bat da.

Ordainketak:VisaMasterCardAmerican ExpressApple PayGoogle PaySEPABancontact