fix(auth): address PR #758 auto-review (id-token verify, nonce, CI key)
Blocking: - AS proxy callback now calls verify_id_token before caching the proxy code so a tampered IdP response can't smuggle identity claims. Important: - Browser OAuth flow generates and verifies an OIDC nonce; new alembic migration 006 adds the nonce column to oauth_sessions. - _origin_matches_self logs a warning when CSRF check is bypassed. - oauth_tools.py uses get_shared_storage instead of fresh handles. Nits: - New token_utils.get_oidc_discovery shares the 5-minute cache with verify_id_token; oauth_login (integrated) and _revoke_refresh_token_at_idp now use it instead of issuing fresh discovery fetches. - Drop typing.Optional from oauth_tools.py in favour of X | None. CI: - test.yml generates an ephemeral Fernet TOKEN_ENCRYPTION_KEY per run with openssl, removing the dependency on a missing repo secret. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
2ef4bfc4af
commit
4c84d82984
@@ -954,6 +954,28 @@ async def _oauth_callback_as_proxy(
|
||||
f"(token_type={nc_token_response.get('token_type')})"
|
||||
)
|
||||
|
||||
# Verify the ID token signature + claims before caching the response
|
||||
# (PR #758 finding 1). Without this, a compromised IdP or tampered
|
||||
# transport could plant arbitrary identity claims into the proxy code
|
||||
# entry that gets handed back to the MCP client. Mirrors the
|
||||
# verification done in oauth_callback_nextcloud.
|
||||
id_token = nc_token_response.get("id_token")
|
||||
try:
|
||||
await verify_id_token(
|
||||
id_token,
|
||||
discovery_url=discovery_url,
|
||||
expected_audience=mcp_server_client_id,
|
||||
)
|
||||
except IdTokenVerificationError as e:
|
||||
logger.error("AS proxy: ID token verification failed: %s", e)
|
||||
return JSONResponse(
|
||||
{
|
||||
"error": "invalid_token",
|
||||
"error_description": "ID token failed verification",
|
||||
},
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
# Generate a proxy authorization code for the client
|
||||
proxy_code = secrets.token_urlsafe(32)
|
||||
_proxy_codes[proxy_code] = ProxyCodeEntry(
|
||||
|
||||
Reference in New Issue
Block a user