modelcontextprotocol / modelcontextprotocol/python-sdk

WWW-Authenticate parsing matches a field name as a substring of another auth-param

Aperta Adatta ai principianti
#3,009 2 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

auth bug P2 v2
Lingua principale
Python
Stelle
24.3k
Fork
4k
Merge medio
1g 1h
PR unite (30g)
31

Descrizione

Describe the bug

Ran into this wiring up an OAuth-protected MCP client. When a 401 WWW-Authenticate challenge carries several auth-params, extract_field_from_www_auth (mcp/client/auth/utils.py) matches the requested field name as a substring of another param's name, so a different param shadows the real value.

The pattern is rf'{field_name}=(?:"([^"]+)"|([^\s,]+))' searched with re.search, with no boundary before field_name.

To reproduce
import httpx
from mcp.client.auth.utils import extract_field_from_www_auth, extract_resource_metadata_from_www_auth

def r(h):
    return httpx.Response(401, headers={"WWW-Authenticate": h},
                          request=httpx.Request("GET", "https://api.example.com/"))

# A real `scope` is present, but `error_scope` shadows it:
print(extract_field_from_www_auth(r('Bearer error_scope="decoy", scope="read write"'), "scope"))
# -> 'decoy'   (expected 'read write')

# Only a decoy param exists; no real `scope`:
print(extract_field_from_www_auth(r('Bearer custom_scope="leaked"'), "scope"))
# -> 'leaked'  (expected None)

# Same for resource_metadata, which drives discovery URL selection:
print(extract_resource_metadata_from_www_auth(r('Bearer x_resource_metadata="https://decoy.example.com"')))
# -> 'https://decoy.example.com'  (expected None)
Expected behavior

The field name should match only as a complete auth-param name (at the header start or after a whitespace/comma separator), so scope doesn't match inside error_scope. This matters most for resource_metadata, since the client uses it to pick the protected-resource-metadata discovery URL — reading it from the wrong param points discovery at the wrong place.

Environment
  • mcp main (reproduces on v1.x as well)

I have a small fix (anchor the param name to the header start or a separator) plus regression cases added to the existing test_extract_field_from_www_auth_* parametrized tests, and can open a PR if this looks right.

Reviewed by AI

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia in mcp/client/auth/utils.py, in extract_field_from_www_auth, e ispeziona i test parametrizzati esistenti test_extract_field_from_www_auth_*. Riproduci i casi con nomi di parametri esca come error_scope e custom_scope, quindi verifica che il parser restituisca solo nomi auth-param completi e che la discovery di resource_metadata ignori le esche.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
python
Ambito
authentication
Tipo di issue
Bug
Difficoltà
2/5
Tempo stimato
1-3 ore
Stato di attività
Tranquilla
Chiarezza
Specificata chiaramente
Idoneità per principianti
78/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.