diff --git a/src/mcp/client/auth/oauth2.py b/src/mcp/client/auth/oauth2.py index 25075dec3..952d2c108 100644 --- a/src/mcp/client/auth/oauth2.py +++ b/src/mcp/client/auth/oauth2.py @@ -458,6 +458,17 @@ async def _handle_refresh_response(self, response: httpx.Response) -> bool: # p content = await response.aread() token_response = OAuthToken.model_validate_json(content) + # Per RFC 6749 Section 6, the server MAY issue a new refresh token. + # If the response omits it, preserve the existing one. + if ( + not token_response.refresh_token + and self.context.current_tokens + and self.context.current_tokens.refresh_token + ): + token_response = token_response.model_copy( + update={"refresh_token": self.context.current_tokens.refresh_token} + ) + self.context.current_tokens = token_response self.context.update_token_expiry(token_response) await self.context.storage.set_tokens(token_response) diff --git a/src/mcp/server/transport_security.py b/src/mcp/server/transport_security.py index 1ed9842c0..34ad4f62c 100644 --- a/src/mcp/server/transport_security.py +++ b/src/mcp/server/transport_security.py @@ -37,8 +37,8 @@ class TransportSecurityMiddleware: """Middleware to enforce DNS rebinding protection for MCP transport endpoints.""" def __init__(self, settings: TransportSecuritySettings | None = None): - # If not specified, disable DNS rebinding protection by default for backwards compatibility - self.settings = settings or TransportSecuritySettings(enable_dns_rebinding_protection=False) + # Secure by default - DNS rebinding protection enabled + self.settings = settings or TransportSecuritySettings(enable_dns_rebinding_protection=True) def _validate_host(self, host: str | None) -> bool: # pragma: no cover """Validate the Host header against allowed values."""