security: redirect_uri-Allowlist + mail Path-Traversal-Schutz

- common.py /authorize: redirect_uri muss https://claude.ai/ oder https://claude.com/ sein
  (verhindert offenen Redirect / Code-Abfluss an fremde URIs).
- mail/server.py _open_folder: realpath-Check, Ordner muss im Account-Verzeichnis
  bleiben (Path-Traversal verhindert).
- tests: get_token_pkce auf sicheren Flow aktualisiert (erlaubte redirect_uri +
  client_secret). 54/54 Tests gruen.
test-Client bleibt (Test-Suite braucht ihn, Secret 600-geschuetzt).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Stefan Lohmaier
2026-06-18 10:09:23 +02:00
parent fc50afa3c8
commit b555a2e19d
3 changed files with 10 additions and 3 deletions
+2 -2
View File
@@ -48,12 +48,12 @@ def get_token_pkce(port):
challenge = base64.urlsafe_b64encode(hashlib.sha256(verifier.encode()).digest()).rstrip(b"=").decode()
r = httpx.get(f"http://127.0.0.1:{port}/authorize", params={
"response_type": "code", "client_id": "test",
"redirect_uri": "http://localhost/cb", "code_challenge": challenge, "code_challenge_method": "S256",
"redirect_uri": "https://claude.ai/api/mcp/auth_callback", "code_challenge": challenge, "code_challenge_method": "S256",
}, follow_redirects=False, timeout=10)
assert r.status_code == 302
code = r.headers["location"].split("code=")[1].split("&")[0]
r2 = httpx.post(f"http://127.0.0.1:{port}/token", data={
"grant_type": "authorization_code", "code": code, "client_id": "test", "code_verifier": verifier,
"grant_type": "authorization_code", "code": code, "client_id": "test", "client_secret": TEST_SECRET, "code_verifier": verifier,
}, timeout=10)
assert r2.status_code == 200
return r2.json()["access_token"]