fix: gate OpenAI catch-all proxy behind ENABLE_OPENAI_API_PASSTHROUGH toggle (#23640)
The catch-all /{path:path} proxy forwards any request to the upstream OpenAI-compatible API with the admin's API key and no access control. This is an intentional proxy but should be opt-in.
Adds ENABLE_OPENAI_API_PASSTHROUGH env var (defaults to False). When disabled, the catch-all returns 403. No other routers (Ollama, responses) have catch-all proxies.
This commit is contained in:
@@ -519,6 +519,11 @@ PASSWORD_VALIDATION_HINT = os.environ.get('PASSWORD_VALIDATION_HINT', '')
|
|||||||
|
|
||||||
BYPASS_MODEL_ACCESS_CONTROL = os.environ.get('BYPASS_MODEL_ACCESS_CONTROL', 'False').lower() == 'true'
|
BYPASS_MODEL_ACCESS_CONTROL = os.environ.get('BYPASS_MODEL_ACCESS_CONTROL', 'False').lower() == 'true'
|
||||||
|
|
||||||
|
# When disabled (default), the OpenAI catch-all proxy endpoint (/{path:path})
|
||||||
|
# is blocked. Enable only if you need direct passthrough to upstream OpenAI-
|
||||||
|
# compatible APIs for endpoints not natively handled by Open WebUI.
|
||||||
|
ENABLE_OPENAI_API_PASSTHROUGH = os.environ.get('ENABLE_OPENAI_API_PASSTHROUGH', 'False').lower() == 'true'
|
||||||
|
|
||||||
WEBUI_AUTH_SIGNOUT_REDIRECT_URL = os.environ.get('WEBUI_AUTH_SIGNOUT_REDIRECT_URL', None)
|
WEBUI_AUTH_SIGNOUT_REDIRECT_URL = os.environ.get('WEBUI_AUTH_SIGNOUT_REDIRECT_URL', None)
|
||||||
|
|
||||||
####################################
|
####################################
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import requests
|
|||||||
|
|
||||||
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
|
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
|
||||||
|
|
||||||
from fastapi import Depends, HTTPException, Request, APIRouter
|
from fastapi import Depends, HTTPException, Request, APIRouter, status
|
||||||
from fastapi.responses import (
|
from fastapi.responses import (
|
||||||
FileResponse,
|
FileResponse,
|
||||||
StreamingResponse,
|
StreamingResponse,
|
||||||
@@ -40,6 +40,7 @@ from open_webui.env import (
|
|||||||
ENABLE_FORWARD_USER_INFO_HEADERS,
|
ENABLE_FORWARD_USER_INFO_HEADERS,
|
||||||
FORWARD_SESSION_INFO_HEADER_CHAT_ID,
|
FORWARD_SESSION_INFO_HEADER_CHAT_ID,
|
||||||
BYPASS_MODEL_ACCESS_CONTROL,
|
BYPASS_MODEL_ACCESS_CONTROL,
|
||||||
|
ENABLE_OPENAI_API_PASSTHROUGH,
|
||||||
)
|
)
|
||||||
from open_webui.models.users import UserModel
|
from open_webui.models.users import UserModel
|
||||||
|
|
||||||
@@ -1438,9 +1439,16 @@ async def responses(
|
|||||||
@router.api_route('/{path:path}', methods=['GET', 'POST', 'PUT', 'DELETE'])
|
@router.api_route('/{path:path}', methods=['GET', 'POST', 'PUT', 'DELETE'])
|
||||||
async def proxy(path: str, request: Request, user=Depends(get_verified_user)):
|
async def proxy(path: str, request: Request, user=Depends(get_verified_user)):
|
||||||
"""
|
"""
|
||||||
Deprecated: proxy all requests to OpenAI API
|
Deprecated: proxy all requests to OpenAI API.
|
||||||
|
Disabled by default. Set ENABLE_OPENAI_API_PASSTHROUGH=True to enable.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if not ENABLE_OPENAI_API_PASSTHROUGH:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_403_FORBIDDEN,
|
||||||
|
detail='Direct API passthrough is disabled. Set ENABLE_OPENAI_API_PASSTHROUGH=True to enable.',
|
||||||
|
)
|
||||||
|
|
||||||
body = await request.body()
|
body = await request.body()
|
||||||
|
|
||||||
# Parse JSON body to resolve model-based routing
|
# Parse JSON body to resolve model-based routing
|
||||||
|
|||||||
Reference in New Issue
Block a user