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
|
QUEUE_MONITOR_INTERVAL=30
|
||||||
|
|
||||||
# Swagger UI configuration
|
# 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
|
SWAGGER_UI_PATH=/swagger-ui.html
|
||||||
|
|
||||||
# Whether to encrypt dataset IDs when exporting DSL files (default: true)
|
# Whether to encrypt dataset IDs when exporting DSL files (default: true)
|
||||||
|
|
|
||||||
|
|
@ -1221,9 +1221,19 @@ class WorkflowLogConfig(BaseSettings):
|
||||||
|
|
||||||
|
|
||||||
class SwaggerUIConfig(BaseSettings):
|
class SwaggerUIConfig(BaseSettings):
|
||||||
SWAGGER_UI_ENABLED: bool = Field(
|
"""
|
||||||
description="Whether to enable Swagger UI in api module",
|
Configuration for Swagger UI documentation.
|
||||||
default=True,
|
|
||||||
|
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(
|
SWAGGER_UI_PATH: str = Field(
|
||||||
|
|
@ -1231,6 +1241,23 @@ class SwaggerUIConfig(BaseSettings):
|
||||||
default="/swagger-ui.html",
|
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):
|
class TenantIsolatedTaskQueueConfig(BaseSettings):
|
||||||
TENANT_ISOLATED_TASK_CONCURRENCY: int = Field(
|
TENANT_ISOLATED_TASK_CONCURRENCY: int = Field(
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,8 @@ login_manager = flask_login.LoginManager()
|
||||||
@login_manager.request_loader
|
@login_manager.request_loader
|
||||||
def load_user_from_request(request_from_flask_login):
|
def load_user_from_request(request_from_flask_login):
|
||||||
"""Load user based on the request."""
|
"""Load user based on the request."""
|
||||||
# Skip authentication for documentation endpoints
|
# 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")):
|
if dify_config.swagger_ui_enabled and request.path.endswith((dify_config.SWAGGER_UI_PATH, "/swagger.json")):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
auth_token = extract_access_token(request)
|
auth_token = extract_access_token(request)
|
||||||
|
|
|
||||||
|
|
@ -131,12 +131,28 @@ class ExternalApi(Api):
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, app: Blueprint | Flask, *args, **kwargs):
|
def __init__(self, app: Blueprint | Flask, *args, **kwargs):
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
|
||||||
kwargs.setdefault("authorizations", self._authorizations)
|
kwargs.setdefault("authorizations", self._authorizations)
|
||||||
kwargs.setdefault("security", "Bearer")
|
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
|
# manual separate call on construction and init_app to ensure configs in kwargs effective
|
||||||
super().__init__(app=None, *args, **kwargs)
|
super().__init__(app=None, *args, **kwargs)
|
||||||
self.init_app(app, **kwargs)
|
self.init_app(app, **kwargs)
|
||||||
register_external_error_handlers(self)
|
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