fix(auth): fail closed on missing sub claim, delete Flow 2 callback session

Addresses the two remaining 🟡 findings from the PR #758 follow-up review:

  1. extract_user_id_from_token previously fell back to "default_user" when
     the verified access token had no sub claim. In a multi-tenant deployment
     a malformed IdP token could have bucketed every request under a single
     sentinel user, risking cross-tenant data exposure. The function now
     raises McpError on that branch; the BasicAuth no-token sentinel path is
     preserved.

  2. oauth_callback_nextcloud (Flow 2) read the PKCE code_verifier from
     oauth_sessions but never deleted the row, leaving the verifier valid for
     the full 10-minute TTL. The row is now deleted eagerly inside the same
     branch, mirroring oauth_login_callback in browser_oauth_routes.

Also wires TOKEN_ENCRYPTION_KEY through the docker-compose step in the CI
test workflow so the integration matrix can boot — every job had been
failing fast on the ${TOKEN_ENCRYPTION_KEY:?...} interpolation guard added
in PR #758 finding 5.

Tests pin both fixes (test_token_utils_user_id.py,
test_oauth_callback_session_cleanup.py).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Chris Coutinho
2026-05-02 19:46:36 +02:00
co-authored by Claude Opus 4.7
parent 2d340a5a6b
commit 2ef4bfc4af
5 changed files with 284 additions and 3 deletions
+5
View File
@@ -139,6 +139,11 @@ jobs:
env:
MCP_SERVER_URL: ${{ matrix.mcp-internal-url }}
NEXTCLOUD_IMAGE: ${{ matrix.nextcloud_image }}
# Required by docker-compose.yml since PR #758 finding 5 (no more
# hardcoded Fernet keys). Generated once and stored as a repo
# secret; the CI tokens.db is ephemeral so a single shared key
# across services is acceptable.
TOKEN_ENCRYPTION_KEY: ${{ secrets.TOKEN_ENCRYPTION_KEY }}
- name: Install the latest version of uv
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0