fastmcp/tests/server
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
..
auth Fix #4292: SSRF guard breaks OAuth/JWKS fetches behind a corporate HTTP proxy (#4412) 2026-07-18 21:42:52 -04:00
http Add subject field to AccessToken initialization (#4267) 2026-07-18 21:15:13 -04:00
middleware Fix typos (#4498) 2026-07-18 21:18:39 -04:00
mount Apply ruff-format: drop now-unused imports and reflow 2026-07-07 07:53:11 -04:00
providers Migrate to MCP SDK v2.0.0b2 (httpx2) (#4503) 2026-07-18 15:12:47 -04:00
sampling Migrate to MCP Python SDK v2 (#4437) 2026-07-06 17:36:45 -04:00
tasks Clean up task sessions on connection exit (#4535) 2026-07-18 15:45:11 -04:00
telemetry Expose telemetry attributes on span start (#4487) 2026-07-18 19:46:19 -04:00
transforms Migrate to MCP Python SDK v2 (#4437) 2026-07-06 17:36:45 -04:00
versioning Migrate to MCP Python SDK v2 (#4437) 2026-07-06 17:36:45 -04:00
__init__.py restore 1.x code 2025-04-09 11:54:42 -04:00
test_app_state.py Update docs and test 2025-06-20 13:06:48 -04:00
test_auth_integration.py Migrate to MCP SDK v2.0.0b2 (httpx2) (#4503) 2026-07-18 15:12:47 -04:00
test_auth_integration_errors.py Migrate to MCP SDK v2.0.0b2 (httpx2) (#4503) 2026-07-18 15:12:47 -04:00
test_cache_hints.py Add server-level cache hints (SEP-2549) (#4464) 2026-07-08 09:10:41 -04:00
test_context.py Migrate to MCP Python SDK v2 (#4437) 2026-07-06 17:36:45 -04:00
test_dependencies.py Capture SharedContext for task-enabled Docket servers (#4443) 2026-07-07 07:48:49 -04:00
test_dependencies_advanced.py Migrate to MCP Python SDK v2 (#4437) 2026-07-06 17:36:45 -04:00
test_event_store.py Migrate to MCP Python SDK v2 (#4437) 2026-07-06 17:36:45 -04:00
test_fastapi_testclient_compat.py fix: FastAPI TestClient compatibility and lifespan re-initialization (#3736) 2026-04-06 19:53:27 -04:00
test_file_server.py Migrate to MCP Python SDK v2 (#4437) 2026-07-06 17:36:45 -04:00
test_icons.py Document icon theme support (#4537) 2026-07-18 20:57:36 -04:00
test_input_validation.py Migrate to MCP Python SDK v2 (#4437) 2026-07-06 17:36:45 -04:00
test_log_level.py Allow pre-bound HTTP sockets (#4222) 2026-05-23 10:08:49 -04:00
test_logging.py Refactor server.py into mixins (#2939) 2026-01-19 11:36:00 -05:00
test_pagination.py Migrate to MCP Python SDK v2 (#4437) 2026-07-06 17:36:45 -04:00
test_protocol_eras.py Use a single fastmcp import style in protocol-era tests 2026-07-06 22:06:22 -04:00
test_providers.py Migrate to MCP Python SDK v2 (#4437) 2026-07-06 17:36:45 -04:00
test_server.py Repoint tests and examples off removed deprecations 2026-07-07 07:53:11 -04:00
test_server_docket.py Make pydocket optional and unify DI systems (#2835) 2026-01-10 16:23:32 -05:00
test_server_lifespan.py Update ty ignore comments for 0.0.25 compatibility (#3614) 2026-03-24 20:26:26 -04:00
test_server_safety.py fix: reject self-mount to prevent infinite recursion (#3925) 2026-04-14 12:10:19 -04:00
test_session_visibility.py Migrate to MCP Python SDK v2 (#4437) 2026-07-06 17:36:45 -04:00
test_streamable_http_no_redirect.py Migrate to MCP SDK v2.0.0b2 (httpx2) (#4503) 2026-07-18 15:12:47 -04:00
test_tool_annotations.py Migrate to MCP Python SDK v2 (#4437) 2026-07-06 17:36:45 -04:00
test_tool_transformation.py Migrate to MCP SDK v2.0.0b2 (httpx2) (#4503) 2026-07-18 15:12:47 -04:00
test_transport.py Forward-port HTTP host guard compatibility (#4474) 2026-07-08 20:55:56 -04:00