TASK-026: Disable API docs in production, protect with BANGUI_ENABLE_DOCS setting
Addresses security concern where FastAPI's default behavior exposes interactive API documentation (/docs, /redoc) without authentication, allowing attackers to enumerate endpoints and understand API schemas. Changes: - Add BANGUI_ENABLE_DOCS boolean setting (default: false) to Settings - Modify create_app() to conditionally set docs_url, redoc_url, openapi_url - Add docs endpoints to SetupRedirectMiddleware allowlist (/api/docs, /api/redoc, /api/openapi.json) - Set BANGUI_ENABLE_DOCS=true in Docker/compose.debug.yml for development - Production compose files leave it unset (defaults to false, docs disabled) - Add comprehensive tests for docs configuration - Document the new setting in Backend-Development.md Security Impact: - API documentation is now disabled by default in production - Development environments can enable docs by setting BANGUI_ENABLE_DOCS=true - Docs endpoints are inaccessible in production without manual configuration Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -143,6 +143,46 @@ def test_create_app_disables_cors_by_default() -> None:
|
||||
assert cors_middleware == []
|
||||
|
||||
|
||||
def test_create_app_disables_api_docs_by_default() -> None:
|
||||
"""API documentation endpoints are disabled when enable_docs is false."""
|
||||
settings = Settings(
|
||||
database_path="/tmp/test.db",
|
||||
fail2ban_socket="/tmp/fake_fail2ban.sock",
|
||||
fail2ban_config_dir="/tmp/fail2ban",
|
||||
session_secret="test-secret-key-do-not-use-in-production",
|
||||
session_duration_minutes=60,
|
||||
timezone="UTC",
|
||||
log_level="debug",
|
||||
enable_docs=False,
|
||||
)
|
||||
|
||||
app = create_app(settings=settings)
|
||||
|
||||
assert app.docs_url is None
|
||||
assert app.redoc_url is None
|
||||
assert app.openapi_url is None
|
||||
|
||||
|
||||
def test_create_app_enables_api_docs_when_configured() -> None:
|
||||
"""API documentation endpoints are enabled at /api/* when enable_docs is true."""
|
||||
settings = Settings(
|
||||
database_path="/tmp/test.db",
|
||||
fail2ban_socket="/tmp/fake_fail2ban.sock",
|
||||
fail2ban_config_dir="/tmp/fail2ban",
|
||||
session_secret="test-secret-key-do-not-use-in-production",
|
||||
session_duration_minutes=60,
|
||||
timezone="UTC",
|
||||
log_level="debug",
|
||||
enable_docs=True,
|
||||
)
|
||||
|
||||
app = create_app(settings=settings)
|
||||
|
||||
assert app.docs_url == "/api/docs"
|
||||
assert app.redoc_url == "/api/redoc"
|
||||
assert app.openapi_url == "/api/openapi.json"
|
||||
|
||||
|
||||
async def test_lifespan_initialises_and_cleans_up_shared_resources(tmp_path: Path) -> None:
|
||||
"""The app lifespan creates and shuts down shared resources cleanly."""
|
||||
settings = Settings(
|
||||
|
||||
Reference in New Issue
Block a user