From 3a9b9a1a748929f1ea447edab6bfad34d25dc256 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Mon, 27 Jul 2026 08:07:34 +0200 Subject: [PATCH] fix: resolve terminal system_oauth token server-side instead of trusting a client header (#26719) The terminal proxy's system_oauth auth type read the OAuth access token from the client-supplied x-oauth-access-token request header and forwarded it verbatim as a Bearer token to the upstream terminal server, so an authenticated caller could substitute an arbitrary token for the one bound to their own session. Resolve the token server-side from the caller's OAuth session via oauth_manager.get_oauth_token(user.id, oauth_session_id), matching the openai.py proxy, so the forwarded token is always the one Open WebUI issued for the authenticated user and the client header is ignored. Co-authored-by: brodmart --- backend/open_webui/routers/terminals.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/backend/open_webui/routers/terminals.py b/backend/open_webui/routers/terminals.py index 191fb96a1f..a66094994e 100644 --- a/backend/open_webui/routers/terminals.py +++ b/backend/open_webui/routers/terminals.py @@ -132,9 +132,18 @@ async def proxy_terminal( headers.update(bearer_auth_header(request.state.token.credentials)) elif auth_type == 'system_oauth': cookies = request.cookies - oauth_token = request.headers.get('x-oauth-access-token', '') + # Resolve the token server-side from the caller's OAuth session; never trust a client header. + oauth_token = None + try: + if request.cookies.get('oauth_session_id', None): + oauth_token = await request.app.state.oauth_manager.get_oauth_token( + user.id, + request.cookies.get('oauth_session_id', None), + ) + except Exception as e: + log.error(f'Error getting OAuth token: {e}') if oauth_token: - headers.update(bearer_auth_header(oauth_token)) + headers.update(bearer_auth_header(oauth_token.get('access_token', ''))) # auth_type == "none": no Authorization header content_type = request.headers.get('content-type')