check_resource_allowed(): path matching skips dot-segment/percent-encoding normalization (auth-boundary bypass)
Ninguém assumiu esta issue ainda.
Avaliação
- Dificuldade
- 3/5
- Tempo estimado
- 1-2 dias
- Facilidade para iniciantes
- 68/100
- Tipo de issue
- Bug
- Clareza
- Claramente especificada
- Status de atividade
- Pouca atividade
- Stack de tecnologia
- python
- Domínio
- authorization, security
Direção de pesquisa
Comece em src/mcp/shared/auth_utils.py, em check_resource_allowed(), e reproduza os exemplos de segmentos de ponto e de codificação percentual da issue. Verifique se os caminhos solicitados normalizados não podem escapar do recurso configurado, enquanto a semântica da barra final permanece intacta, e então execute os testes relevantes dos utilitários de autenticação.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
Summary
check_resource_allowed() in src/mcp/shared/auth_utils.py performs hierarchical path matching with str.startswith() after only trailing-slash normalization. It does not resolve dot-segments (.., .) or decode percent-encoding, so a requested resource can satisfy startswith(configured) while resolving to a path outside the configured resource.
This is a confused-deputy / path-traversal gap at the resource-authorization boundary: any downstream resource server that normalizes paths (most do) will serve a different resource than the one the SDK authorized.
Reproduction
from mcp.shared.auth_utils import check_resource_allowed
# Access to /api is configured; /admin is NOT
configured = "https://mcp.example.com/api"
requested = "https://mcp.example.com/api/../admin"
print(check_resource_allowed(requested, configured)) # -> True (should be False)
The current code normalizes to /api/../admin/ vs /api/, and "/api/../admin/".startswith("/api/") is True. The resolved path is /admin. Percent-encoded variants (%2e%2e) bypass it the same way.
Impact
Where the result gates access to a protected resource, a caller can craft a resource indicator that passes the check but points elsewhere. Severity depends on deployment, but it's an auth-boundary correctness bug, not cosmetic.
Fix
Decode percent-encoding and resolve dot-segments (posixpath.normpath after unquote) on both paths before the startswith comparison, preserving trailing-slash semantics. A patch implementing exactly this was opened as #2585 and closed in the post-v2 backlog sweep with the note to reopen if still relevant against v2 — filing this issue per CONTRIBUTING so it can be triaged. The bug is present verbatim on current main. Happy to refresh the PR against v2 once triaged.
- Linguagem predominante
- Python
- Estrelas
- 24.3k
- Forks
- 4k
- Merge médio
- 1d 11h
- PRs com merge (30d)
- 30
Guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de modelcontextprotocol/python-sdk
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 75/100
modelcontextprotocol/python-sdk#3566 ·
-
v1 v2
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 85/100
modelcontextprotocol/python-sdk#3546 · 5 comentários ·
-
v1 v2
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 76/100
modelcontextprotocol/python-sdk#3545 · 1 comentário ·
-
v1 v2
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 91/100
modelcontextprotocol/python-sdk#3508 · 2 comentários ·
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 64/100
modelcontextprotocol/python-sdk#3504 ·
Todas as issues de modelcontextprotocol/python-sdk
Issues semelhantes
-
bug confirmed issue
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 75/100
open-webui/open-webui#30750 · 1 comentário ·
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 75/100
-
enhancement
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 75/100
OpenwaterHealth/openmotion-bloodflow-app#604 · 1 comentário ·
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 70/100
-
good first issue
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 90/100