modelcontextprotocol / modelcontextprotocol/python-sdk

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

未关闭 适合新手
#3,009 2 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

auth bug P2 v2
主要语言
Python
星标
24.3k
派生
4k
平均合并
1 天 1 小时
30 天内合并 PR
31

描述

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

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

从 mcp/client/auth/utils.py 中的 extract_field_from_www_auth 开始,检查现有的参数化测试 test_extract_field_from_www_auth_*。复现包含 error_scope 和 custom_scope 等诱饵参数名的用例,然后验证解析器只返回完整的 auth-param 名称,并且 resource_metadata 发现会忽略诱饵参数。

由索引模型根据 Issue 内容生成。

评估

技术栈
python
领域
authentication
Issue 类型
缺陷
难度
2/5
预计耗时
1-3 小时
活跃度
冷清
描述清晰度
描述清楚
新手友好度
78/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。