Browse Source

Add authentication to bug report debug logging endpoints

  The bug report endpoints (start-logging, stop-logging, submit) had no
  authentication, allowing anyone on the network to enable debug logging,
  retrieve sanitized system logs, and trigger bug report submissions when
  auth was enabled. All three now require permission when auth is enabled:
  start-logging requires settings:update, stop-logging and submit require
  settings:read. Endpoints remain open when auth is disabled (default).
maziggy 1 month ago
parent
commit
5709282200
2 changed files with 16 additions and 4 deletions
  1. 1 0
      CHANGELOG.md
  2. 15 4
      backend/app/api/routes/bug_report.py

+ 1 - 0
CHANGELOG.md

@@ -17,6 +17,7 @@ All notable changes to Bambuddy will be documented in this file.
 
 ### Security
 - **Path Traversal in File Upload Endpoints** — Archive upload endpoints (`/upload`, `/upload-bulk`, `/{id}/source`, `/source-by-name`, `/{id}/f3d`, `/{id}/timelapse`) used the client-supplied filename directly in file paths without stripping directory components. An authenticated attacker could write files outside the intended directory via directory traversal (e.g. `../../evil.3mf`). All upload endpoints now sanitize filenames by extracting only the basename before constructing paths. Reported responsibly by Sacha Vaudey via security@bambuddy.cool.
+- **Unauthenticated Bug Report Endpoints** — The bug report endpoints (`/start-logging`, `/stop-logging`, `/submit`) had no authentication, allowing anyone on the network to enable debug logging, retrieve system logs, and trigger bug report submissions with system diagnostics when authentication was enabled. All three endpoints now require authentication — `start-logging` requires `settings:update` permission, `stop-logging` and `submit` require `settings:read`. Endpoints remain open when authentication is disabled (the default). Reported responsibly by Sacha Vaudey via security@bambuddy.cool.
 
 ### Fixed
 - **Thumbnails Broken After Backend Restart** — Archive and library thumbnails returned 401 Unauthorized after a backend restart because stream tokens are stored in memory and lost on restart. The frontend now detects failed token-protected image loads and automatically refreshes the stream token, so thumbnails recover without a page reload.

+ 15 - 4
backend/app/api/routes/bug_report.py

@@ -12,7 +12,10 @@ from backend.app.api.routes.support import (
     _get_recent_sanitized_logs,
     _set_debug_setting,
 )
+from backend.app.core.auth import RequirePermissionIfAuthEnabled
 from backend.app.core.database import async_session
+from backend.app.core.permissions import Permission
+from backend.app.models.user import User
 from backend.app.services.bug_report import submit_report
 from backend.app.services.printer_manager import printer_manager
 
@@ -45,7 +48,9 @@ class StopLoggingResponse(BaseModel):
 
 
 @router.post("/start-logging", response_model=StartLoggingResponse)
-async def start_logging():
+async def start_logging(
+    _: User | None = RequirePermissionIfAuthEnabled(Permission.SETTINGS_UPDATE),
+):
     """Enable debug logging and push all printers for fresh data."""
     async with async_session() as db:
         was_debug, _ = await _get_debug_setting(db)
@@ -66,7 +71,10 @@ async def start_logging():
 
 
 @router.post("/stop-logging", response_model=StopLoggingResponse)
-async def stop_logging(was_debug: bool = Query(default=False)):
+async def stop_logging(
+    was_debug: bool = Query(default=False),
+    _: User | None = RequirePermissionIfAuthEnabled(Permission.SETTINGS_READ),
+):
     """Collect logs and restore previous log level."""
     logs = await _get_recent_sanitized_logs()
 
@@ -80,8 +88,11 @@ async def stop_logging(was_debug: bool = Query(default=False)):
 
 
 @router.post("/submit", response_model=BugReportResponse)
-async def submit_bug_report(report: BugReportRequest):
-    """Submit a bug report. No auth required — anyone should be able to report bugs."""
+async def submit_bug_report(
+    report: BugReportRequest,
+    _: User | None = RequirePermissionIfAuthEnabled(Permission.SETTINGS_READ),
+):
+    """Submit a bug report. Requires auth when authentication is enabled."""
     support_info = None
     if report.include_support_info:
         try: