OAuth authorize error paths: open redirect via unvalidated redirect_uri
⚠️ Search for existing issues first ⚠️
- I have searched the existing issues, and there is no existing issue for my problem
Which Operating System are you using?
Docker
Which version of AutoGPT are you using?
Master (branch)
What LLM Provider do you use?
Other (detail in issue)
Which area covers your issue best?
Other
What commit or version are you using?
c035ab1f91b8556f86e87be26dcaf31677f64ba5
Describe your issue.
POST /api/oauth/authorize only validates redirect_uri on the success path. The three error branches — unsupported response_type (:194), unknown client_id (:204), application not active (:212) — return HTTP 200 with a redirect_url built by string-concatenating the request-supplied redirect_uri, with no scheme/host/registration check. Whatever URI the caller puts in the request is handed back as the browser navigation target, and the frontend consent page navigates to whatever redirect_url it receives — so an attacker who crafts an authorize request with redirect_uri=https://evil.example/phish and gets a victim to open it lands the victim on the attacker's page with OAuth error codes and state appended. This is an open redirect in practice, not just a stray JSON field.
For comparison: the validation does exist — the same unregistered redirect_uri with a valid client and the supported response_type=code is correctly rejected with 400 — it just runs after the error branches have already returned. Per RFC 6749 §4.1.2.1 an unknown/invalid client must not be redirected at all, and error redirects may only target a registered redirect URI.
Expected behavior
Every error branch resolves the client and validates the redirect_uri first; unregistered URIs get 400/JSON errors, never a redirect.
Actual behavior
# Variant 1 — the leak, via the "unsupported response_type" error branch:
# valid client, but attacker-controlled redirect_uri + unsupported response_type=token
curl -X POST http://127.0.0.1:8006/api/oauth/authorize \
-H "Authorization: Bearer $USER_TOKEN" -H "Content-Type: application/json" \
-d '{"client_id":"poc-app","redirect_uri":"https://evil.example/phish",
"response_type":"token","state":"st123"}'
# → HTTP 200 {"redirect_url":"https://evil.example/phish?error=unsupported_response_type&state=st123&…"}
# the attacker-controlled URI is returned unvalidated; the consent page will navigate to it
# Variant 2 — same leak on a second error branch ("unknown client_id"):
curl -X POST http://127.0.0.1:8006/api/oauth/authorize \
-H "Authorization: Bearer $USER_TOKEN" -H "Content-Type: application/json" \
-d '{"client_id":"no-such-app","redirect_uri":"https://evil.example/phish2",
"response_type":"code","state":"st123"}'
# → HTTP 200 {"redirect_url":"https://evil.example/phish2?error=invalid_client&state=st123&…"}
# RFC 6749 §4.1.2.1: an unknown client_id must not produce a redirect at all
# Control — proof that redirect_uri validation exists but runs too late:
# valid client + the supported response_type=code, so the request survives to the
# validation step, which correctly rejects the unregistered URI
curl -X POST http://127.0.0.1:8006/api/oauth/authorize \
-H "Authorization: Bearer $USER_TOKEN" -H "Content-Type: application/json" \
-d '{"client_id":"poc-app","redirect_uri":"https://evil.example/phish",
"response_type":"code","state":"st123"}'
# → HTTP 400 "Invalid redirect_uri. Must be one of: http://localhost:3000/callback"Upload Activity Log Content
No response
Upload Error Log Content
No response
Source: Significant-Gravitas/AutoGPT