mirror of https://github.com/langgenius/dify.git
security/fix-swagger-info-leak-m02 (#29283)
Co-authored-by: crazywoola <100913391+crazywoola@users.noreply.github.com>
This commit is contained in:
parent
7fead6a9da
commit
355a2356d4
|
|
@ -626,7 +626,17 @@ QUEUE_MONITOR_ALERT_EMAILS=
|
|||
QUEUE_MONITOR_INTERVAL=30
|
||||
|
||||
# Swagger UI configuration
|
||||
SWAGGER_UI_ENABLED=true
|
||||
# SECURITY: Swagger UI is automatically disabled in PRODUCTION environment (DEPLOY_ENV=PRODUCTION)
|
||||
# to prevent API information disclosure.
|
||||
#
|
||||
# Behavior:
|
||||
# - DEPLOY_ENV=PRODUCTION + SWAGGER_UI_ENABLED not set -> Swagger DISABLED (secure default)
|
||||
# - DEPLOY_ENV=DEVELOPMENT/TESTING + SWAGGER_UI_ENABLED not set -> Swagger ENABLED
|
||||
# - SWAGGER_UI_ENABLED=true -> Swagger ENABLED (overrides environment check)
|
||||
# - SWAGGER_UI_ENABLED=false -> Swagger DISABLED (explicit disable)
|
||||
#
|
||||
# For development, you can uncomment below or set DEPLOY_ENV=DEVELOPMENT
|
||||
# SWAGGER_UI_ENABLED=false
|
||||
SWAGGER_UI_PATH=/swagger-ui.html
|
||||
|
||||
# Whether to encrypt dataset IDs when exporting DSL files (default: true)
|
||||
|
|
|
|||
|
|
@ -1221,9 +1221,19 @@ class WorkflowLogConfig(BaseSettings):
|
|||
|
||||
|
||||
class SwaggerUIConfig(BaseSettings):
|
||||
SWAGGER_UI_ENABLED: bool = Field(
|
||||
description="Whether to enable Swagger UI in api module",
|
||||
default=True,
|
||||
"""
|
||||
Configuration for Swagger UI documentation.
|
||||
|
||||
Security Note: Swagger UI is automatically disabled in PRODUCTION environment
|
||||
to prevent API information disclosure. Set SWAGGER_UI_ENABLED=true explicitly
|
||||
to enable in production if needed.
|
||||
"""
|
||||
|
||||
SWAGGER_UI_ENABLED: bool | None = Field(
|
||||
description="Whether to enable Swagger UI in api module. "
|
||||
"Automatically disabled in PRODUCTION environment for security. "
|
||||
"Set to true explicitly to enable in production.",
|
||||
default=None,
|
||||
)
|
||||
|
||||
SWAGGER_UI_PATH: str = Field(
|
||||
|
|
@ -1231,6 +1241,23 @@ class SwaggerUIConfig(BaseSettings):
|
|||
default="/swagger-ui.html",
|
||||
)
|
||||
|
||||
@property
|
||||
def swagger_ui_enabled(self) -> bool:
|
||||
"""
|
||||
Compute whether Swagger UI should be enabled.
|
||||
|
||||
If SWAGGER_UI_ENABLED is explicitly set, use that value.
|
||||
Otherwise, disable in PRODUCTION environment for security.
|
||||
"""
|
||||
if self.SWAGGER_UI_ENABLED is not None:
|
||||
return self.SWAGGER_UI_ENABLED
|
||||
|
||||
# Auto-disable in production environment
|
||||
import os
|
||||
|
||||
deploy_env = os.environ.get("DEPLOY_ENV", "PRODUCTION")
|
||||
return deploy_env.upper() != "PRODUCTION"
|
||||
|
||||
|
||||
class TenantIsolatedTaskQueueConfig(BaseSettings):
|
||||
TENANT_ISOLATED_TASK_CONCURRENCY: int = Field(
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ login_manager = flask_login.LoginManager()
|
|||
@login_manager.request_loader
|
||||
def load_user_from_request(request_from_flask_login):
|
||||
"""Load user based on the request."""
|
||||
# Skip authentication for documentation endpoints
|
||||
if dify_config.SWAGGER_UI_ENABLED and request.path.endswith((dify_config.SWAGGER_UI_PATH, "/swagger.json")):
|
||||
# Skip authentication for documentation endpoints (only when Swagger is enabled)
|
||||
if dify_config.swagger_ui_enabled and request.path.endswith((dify_config.SWAGGER_UI_PATH, "/swagger.json")):
|
||||
return None
|
||||
|
||||
auth_token = extract_access_token(request)
|
||||
|
|
|
|||
|
|
@ -131,12 +131,28 @@ class ExternalApi(Api):
|
|||
}
|
||||
|
||||
def __init__(self, app: Blueprint | Flask, *args, **kwargs):
|
||||
import logging
|
||||
import os
|
||||
|
||||
kwargs.setdefault("authorizations", self._authorizations)
|
||||
kwargs.setdefault("security", "Bearer")
|
||||
kwargs["add_specs"] = dify_config.SWAGGER_UI_ENABLED
|
||||
kwargs["doc"] = dify_config.SWAGGER_UI_PATH if dify_config.SWAGGER_UI_ENABLED else False
|
||||
|
||||
# Security: Use computed swagger_ui_enabled which respects DEPLOY_ENV
|
||||
swagger_enabled = dify_config.swagger_ui_enabled
|
||||
kwargs["add_specs"] = swagger_enabled
|
||||
kwargs["doc"] = dify_config.SWAGGER_UI_PATH if swagger_enabled else False
|
||||
|
||||
# manual separate call on construction and init_app to ensure configs in kwargs effective
|
||||
super().__init__(app=None, *args, **kwargs)
|
||||
self.init_app(app, **kwargs)
|
||||
register_external_error_handlers(self)
|
||||
|
||||
# Security: Log warning when Swagger is enabled in production environment
|
||||
deploy_env = os.environ.get("DEPLOY_ENV", "PRODUCTION")
|
||||
if swagger_enabled and deploy_env.upper() == "PRODUCTION":
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.warning(
|
||||
"SECURITY WARNING: Swagger UI is ENABLED in PRODUCTION environment. "
|
||||
"This may expose sensitive API documentation. "
|
||||
"Set SWAGGER_UI_ENABLED=false or remove the explicit setting to disable."
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in New Issue