fastmcp/tests/server/auth
Alexander Savchuk 2899ffb6f3
Fix #4292: SSRF guard breaks OAuth/JWKS fetches behind a corporate HTTP proxy (#4412)
* Add FASTMCP_SSRF_TRUST_PROXY to allow SSRF fetches through a corporate proxy

🤖 Generated with Claude Code

* Make SSRF fetch client trust_env explicit for proxy routing

🤖 Generated with Claude Code

* Warn when SSRF proxy trust is enabled without a configured proxy

🤖 Generated with Claude Code

* Warn when NO_PROXY would send an SSRF-trust-proxy fetch direct

🤖 Generated with Claude Code

* Refuse SSRF-trust-proxy fetches when no proxy would route the target

🤖 Generated with Claude Code

* Fix TestProxyMode mocks to patch httpx2.AsyncClient

main's httpx -> httpx2 migration (#4503) landed after these tests were
written; ssrf.py's fetch path already uses httpx2.AsyncClient, but
TestProxyMode still patched the old httpx module, so the mock silently
stopped intercepting and requests escaped to the real network.

* Fix port-qualified NO_PROXY bypass in SSRF proxy-trust guard

proxy_bypass(hostname) discarded the port, so a NO_PROXY entry like
127.0.0.1:8443 went undetected while httpx2 honored it and sent the
request direct with the blocklist already disabled. Pass host:port
instead, except for IPv6 literals, where httpx2 ignores port when
matching NO_PROXY and neither bracketed nor unbracketed host:port
reliably matches through proxy_bypass()'s own parser.

* Replace NO_PROXY prediction with explicit proxy control in SSRF trust-proxy mode

Predicting httpx2's proxy routing (via proxy_bypass(), then via httpx2's own
get_environment_proxies()/URLPattern internals) kept diverging from its real
NO_PROXY handling — three rounds, three different divergences, always in the
unsafe direction. Read HTTPS_PROXY/ALL_PROXY directly and pass it to httpx2
explicitly with trust_env=False, so the request provably goes through that
proxy instead of being predicted to. NO_PROXY is no longer evaluated in this
mode: a NO_PROXY'd host is now routed through the proxy rather than refused,
since that's strictly safer than the alternative (direct with the blocklist
already off).

---------

Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
2026-07-18 21:42:52 -04:00
..
oauth_proxy Add server-side identity assertion (SEP-990 ID-JAG) (#4483) 2026-07-18 19:52:15 -04:00
providers Add subject field to AccessToken initialization (#4267) 2026-07-18 21:15:13 -04:00
__init__.py Add WorkOS and Azure OAuth providers (#1550) 2025-08-20 16:22:03 -04:00
test_auth_provider.py Migrate to MCP SDK v2.0.0b2 (httpx2) (#4503) 2026-07-18 15:12:47 -04:00
test_authorization.py Migrate to MCP Python SDK v2 (#4437) 2026-07-06 17:36:45 -04:00
test_cimd.py Stabilize upgraded ty checks (#4526) 2026-07-17 17:46:53 -04:00
test_cimd_validators.py Split large test files to comply with loq line limit (#3328) 2026-02-28 11:21:11 -05:00
test_debug_verifier.py Add DebugTokenVerifier with custom sync/async validation (#2296) 2025-10-31 10:38:01 -04:00
test_enhanced_error_responses.py Include scopes in auth challenges (#4527) 2026-07-18 20:53:52 -04:00
test_jwt_issuer.py Migrate auth JWTs to joserfc (#4221) 2026-05-23 09:29:04 -04:00
test_jwt_provider.py Add subject field to AccessToken initialization (#4267) 2026-07-18 21:15:13 -04:00
test_jwt_provider_bearer.py Migrate to MCP SDK v2.0.0b2 (httpx2) (#4503) 2026-07-18 15:12:47 -04:00
test_multi_auth.py Include scopes in auth challenges (#4527) 2026-07-18 20:53:52 -04:00
test_oauth_consent_flow.py Reject dot-segments in redirect URI allowlist matching (#3963) 2026-04-17 17:49:25 -04:00
test_oauth_consent_page.py Migrate to MCP Python SDK v2 (#4437) 2026-07-06 17:36:45 -04:00
test_oauth_mounting.py Migrate to MCP SDK v2.0.0b2 (httpx2) (#4503) 2026-07-18 15:12:47 -04:00
test_oauth_proxy_redirect_validation.py Block unsafe OAuth redirect schemes (#4419) 2026-07-05 17:16:10 -04:00
test_oauth_proxy_storage.py Migrate to MCP Python SDK v2 (#4437) 2026-07-06 17:36:45 -04:00
test_oidc_proxy.py Migrate to MCP SDK v2.0.0b2 (httpx2) (#4503) 2026-07-18 15:12:47 -04:00
test_oidc_proxy_token.py fix: use intent-based flag for OIDC scope patch in load_access_token (#3465) 2026-03-13 17:59:03 -04:00
test_redirect_validation.py Block unsafe OAuth redirect schemes (#4419) 2026-07-05 17:16:10 -04:00
test_remote_auth_provider.py Include scopes in auth challenges (#4527) 2026-07-18 20:53:52 -04:00
test_ssrf_protection.py Fix #4292: SSRF guard breaks OAuth/JWKS fetches behind a corporate HTTP proxy (#4412) 2026-07-18 21:42:52 -04:00
test_static_token_verifier.py Add subject field to AccessToken initialization (#4267) 2026-07-18 21:15:13 -04:00