mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-24 06:24:18 +02:00
Screen templated resource parameters for path traversal by default (#4482)
* Add ResourceSecurity screening for templated resources (defaults on)
* Add tests for resource path-security screening
* Document resource path-security; fix ty in tests
* Carry child template security policy through provider mount
Preserve a mounted template's explicit ResourceSecurity (per-param
exemptions or a deliberate opt-out) through FastMCPProviderResourceTemplate.wrap
so the parent read chokepoint honours it instead of the parent default.
* Defer mcp SDK import so fastmcp.resources loads without the [mcp] extra
* Make resource path-security docs examples self-contained and runnable
* Match exempt_params under both hyphen and underscore spellings
Template placeholders like {git-ref} extract as git_ref, so an exemption
written with the natural URI-template spelling never matched.
* Docs: describe net-depth traversal rule accurately; make example runnable
The screening only rejects .. segments that escape the starting depth
(foo/../bar passes) — saying any standalone .. is rejected overstated
the guarantee. Also define DOCS_ROOT so the example runs.
This commit is contained in:
parent
918b85f9b2
commit
d779414f8a
12 changed files with 824 additions and 11 deletions
|
|
@ -762,14 +762,15 @@ class TestResourceTemplateRequestBuilding:
|
|||
mcp.add_provider(provider)
|
||||
|
||||
async with Client(mcp) as mcp_client:
|
||||
await mcp_client.read_resource(
|
||||
"resource://get_user/..%2F..%2Fadmin%2Fsecret"
|
||||
)
|
||||
# Reserved characters (encoded slash + space) must be
|
||||
# re-encoded when building the outbound URL. A traversal
|
||||
# payload (`..%2F...`) would be rejected by the default
|
||||
# resource-security screening, so use a benign value that
|
||||
# still exercises reserved-character encoding.
|
||||
await mcp_client.read_resource("resource://get_user/a%2Fb%20c")
|
||||
|
||||
assert seen_urls == [
|
||||
httpx.URL(
|
||||
"https://api.example.com/api/v1/users/%2E%2E%2F%2E%2E%2Fadmin%2Fsecret"
|
||||
)
|
||||
httpx.URL("https://api.example.com/api/v1/users/a%2Fb%20c")
|
||||
]
|
||||
|
||||
async def test_resource_template_ignores_unmatched_query_string(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue