fix(security): validate Bearer token value in MCP endpoints, not just presence
Previously any Bearer token (even invalid) passed the HTTP middleware and got a session with access to tools/list and resources/list. Now the OAuthRequiredMiddleware validates tokens against master key, API keys, and OAuth JWT before allowing initialize. Also fixes: - WordPress Advanced env prefix: WORDPRESS_ → WORDPRESS_ADVANCED_ in docs - Bump version to 3.0.1 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -108,7 +108,7 @@ Add more sites with `SITE2`, `SITE3`, etc. See [full configuration guide](https:
|
||||
|--------|-------|------------|
|
||||
| WordPress | 67 | `WORDPRESS_` |
|
||||
| WooCommerce | 28 | `WOOCOMMERCE_` |
|
||||
| WordPress Advanced | 22 | `WORDPRESS_` |
|
||||
| WordPress Advanced | 22 | `WORDPRESS_ADVANCED_` |
|
||||
| Gitea | 56 | `GITEA_` |
|
||||
| n8n | 56 | `N8N_` |
|
||||
| Supabase | 70 | `SUPABASE_` |
|
||||
|
||||
@@ -1995,7 +1995,7 @@ def _get_project_version() -> str:
|
||||
return line.split("=")[1].strip().strip('"').strip("'")
|
||||
except Exception:
|
||||
pass
|
||||
return "3.0.0"
|
||||
return "3.0.1"
|
||||
|
||||
|
||||
def get_about_info() -> dict:
|
||||
|
||||
@@ -138,7 +138,7 @@
|
||||
|
||||
<!-- Footer -->
|
||||
<p class="text-center text-gray-500 text-sm mt-6">
|
||||
MCP Hub v{{ version|default('3.0.0') }}
|
||||
MCP Hub v{{ version|default('3.0.1') }}
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -319,7 +319,7 @@ MCP Hub supports **Open Dynamic Client Registration** (RFC 7591). ChatGPT can au
|
||||
|--------|-------|------------|
|
||||
| WordPress | 67 | `WORDPRESS_` |
|
||||
| WooCommerce | 28 | `WOOCOMMERCE_` |
|
||||
| WordPress Advanced | 22 | `WORDPRESS_` (same sites, advanced ops) |
|
||||
| WordPress Advanced | 22 | `WORDPRESS_ADVANCED_` |
|
||||
| Gitea | 56 | `GITEA_` |
|
||||
| n8n | 56 | `N8N_` |
|
||||
| Supabase | 70 | `SUPABASE_` |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "mcphub-server"
|
||||
version = "3.0.0"
|
||||
version = "3.0.1"
|
||||
description = "AI-native management hub for WordPress, WooCommerce, and self-hosted services via Model Context Protocol (MCP)"
|
||||
authors = [
|
||||
{name = "MCP Hub", email = "contact@mcphub.dev"}
|
||||
|
||||
46
server.py
46
server.py
@@ -4053,8 +4053,54 @@ def create_multi_endpoint_app(transport: str = "streamable-http"):
|
||||
},
|
||||
)
|
||||
|
||||
# Validate the token value (not just presence)
|
||||
token = auth_header.removeprefix("Bearer ").strip()
|
||||
if token and not self._is_valid_token(token):
|
||||
base_url = get_oauth_base_url(request)
|
||||
resource_metadata_url = f"{base_url}/.well-known/oauth-protected-resource"
|
||||
logger.warning(f"MCP OAuth: Invalid token for {path}")
|
||||
|
||||
return Response(
|
||||
content='{"error": "invalid_token", "error_description": "Bearer token is invalid"}',
|
||||
status_code=401,
|
||||
media_type="application/json",
|
||||
headers={
|
||||
"WWW-Authenticate": f'Bearer resource_metadata="{resource_metadata_url}", error="invalid_token"',
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"Access-Control-Allow-Headers": "Authorization, Content-Type",
|
||||
"Access-Control-Expose-Headers": "WWW-Authenticate",
|
||||
},
|
||||
)
|
||||
|
||||
return await call_next(request)
|
||||
|
||||
@staticmethod
|
||||
def _is_valid_token(token: str) -> bool:
|
||||
"""Check if a Bearer token is recognized by any auth backend."""
|
||||
# 1. Master API key
|
||||
if auth_manager.validate_master_key(token):
|
||||
return True
|
||||
|
||||
# 2. Per-project API key (any valid key, skip project/scope check)
|
||||
if token.startswith("cmp_"):
|
||||
key_hash = api_key_manager._hash_key(token)
|
||||
for key in api_key_manager.keys.values():
|
||||
if key.key_hash == key_hash and key.is_valid():
|
||||
return True
|
||||
return False
|
||||
|
||||
# 3. OAuth JWT token
|
||||
try:
|
||||
from core.oauth import get_token_manager
|
||||
|
||||
token_manager = get_token_manager()
|
||||
if token_manager.validate_access_token(token):
|
||||
return True
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return False
|
||||
|
||||
# Create MCP instances
|
||||
system_mcp = create_system_mcp() # Phase X.3 - System endpoint
|
||||
wp_mcp = create_wordpress_mcp()
|
||||
|
||||
Reference in New Issue
Block a user