mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-23 14:04:18 +02:00
Raise error when http_client and ssrf_safe=True are both provided
🤖 Generated with Claude Code https://claude.ai/code/session_012QKWmKd21vypDmxWbwuE4e
This commit is contained in:
parent
1704ffe88f
commit
730175910c
3 changed files with 21 additions and 14 deletions
|
|
@ -364,6 +364,10 @@ verifier = JWTVerifier(
|
|||
)
|
||||
```
|
||||
|
||||
<Warning>
|
||||
`JWTVerifier` does not support `http_client` when `ssrf_safe=True`. SSRF-safe mode requires a hardened transport that validates DNS resolution and connection targets, which cannot be guaranteed with a user-provided client. Attempting to use both will raise a `ValueError`.
|
||||
</Warning>
|
||||
|
||||
<Note>
|
||||
When you provide an `http_client`, you are responsible for its lifecycle. The verifier will not close it. Use the server's `lifespan` to manage client cleanup:
|
||||
|
||||
|
|
|
|||
|
|
@ -189,10 +189,11 @@ class JWTVerifier(TokenVerifier):
|
|||
http_client: Optional httpx.AsyncClient for connection pooling. When provided,
|
||||
the client is reused for JWKS fetches and the caller is responsible for
|
||||
its lifecycle. When None (default), a fresh client is created per fetch.
|
||||
Only used when ssrf_safe is False; SSRF-safe fetches use their own transport.
|
||||
Cannot be used with ssrf_safe=True.
|
||||
|
||||
Raises:
|
||||
ValueError: If neither or both of `public_key` and `jwks_uri` are provided, or if `algorithm` is unsupported.
|
||||
ValueError: If neither or both of `public_key` and `jwks_uri` are provided,
|
||||
if `algorithm` is unsupported, or if `http_client` is provided with `ssrf_safe=True`.
|
||||
"""
|
||||
if not public_key and not jwks_uri:
|
||||
raise ValueError("Either public_key or jwks_uri must be provided")
|
||||
|
|
@ -200,6 +201,12 @@ class JWTVerifier(TokenVerifier):
|
|||
if public_key and jwks_uri:
|
||||
raise ValueError("Provide either public_key or jwks_uri, not both")
|
||||
|
||||
if ssrf_safe and http_client is not None:
|
||||
raise ValueError(
|
||||
"http_client cannot be used with ssrf_safe=True; "
|
||||
"SSRF-safe mode requires its own hardened transport"
|
||||
)
|
||||
|
||||
algorithm = algorithm or "RS256"
|
||||
if algorithm not in {
|
||||
"HS256",
|
||||
|
|
|
|||
|
|
@ -180,21 +180,17 @@ class TestJWTVerifierHttpClient:
|
|||
assert result is not None
|
||||
assert not shared_client.is_closed
|
||||
|
||||
async def test_ssrf_safe_ignores_http_client(
|
||||
def test_ssrf_safe_rejects_http_client(
|
||||
self,
|
||||
shared_client: httpx.AsyncClient,
|
||||
):
|
||||
"""When ssrf_safe=True, the custom http_client should NOT be used."""
|
||||
verifier = JWTVerifier(
|
||||
jwks_uri="https://auth.example.com/.well-known/jwks.json",
|
||||
ssrf_safe=True,
|
||||
http_client=shared_client,
|
||||
)
|
||||
|
||||
# ssrf_safe uses ssrf_safe_fetch instead of httpx.AsyncClient
|
||||
# The http_client is stored but not used in this code path
|
||||
assert verifier._http_client is shared_client
|
||||
assert verifier.ssrf_safe is True
|
||||
"""ssrf_safe=True and http_client cannot be used together."""
|
||||
with pytest.raises(ValueError, match="cannot be used with ssrf_safe=True"):
|
||||
JWTVerifier(
|
||||
jwks_uri="https://auth.example.com/.well-known/jwks.json",
|
||||
ssrf_safe=True,
|
||||
http_client=shared_client,
|
||||
)
|
||||
|
||||
|
||||
class TestGitHubHttpClient:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue