fix(security): stop leaking webhook tokens via httpx debug logging

Settings → Support → Debug Logging elevated httpx/httpcore to DEBUG,
  which makes httpx log every outbound request URL. For Discord and
  generic webhook notifications the bearer token is embedded in the URL
  path, so users who turned on debug logging to capture a support bundle
  were writing their webhook tokens straight into bambuddy.log.

  Pin httpx/httpcore to WARNING regardless of the debug toggle. paho.mqtt
  still honours debug. Users who enabled debug logging while notifications
  were sending must rotate any exposed Discord/webhook URLs — the token
  is the path, so the whole URL has to be regenerated in the provider UI.
This commit is contained in:
maziggy
2026-04-14 09:13:55 +02:00
parent 3762022444
commit b71b721658
3 changed files with 14 additions and 15 deletions
+8 -12
View File
@@ -103,18 +103,14 @@ def _apply_log_level(debug: bool):
for handler in root_logger.handlers:
handler.setLevel(new_level)
# Also adjust third-party loggers
if debug:
logging.getLogger("sqlalchemy.engine").setLevel(logging.WARNING)
logging.getLogger("aiosqlite").setLevel(logging.WARNING)
logging.getLogger("httpcore").setLevel(logging.DEBUG)
logging.getLogger("httpx").setLevel(logging.DEBUG)
logging.getLogger("paho.mqtt").setLevel(logging.DEBUG)
else:
logging.getLogger("sqlalchemy.engine").setLevel(logging.WARNING)
logging.getLogger("httpcore").setLevel(logging.WARNING)
logging.getLogger("httpx").setLevel(logging.WARNING)
logging.getLogger("paho.mqtt").setLevel(logging.WARNING)
# Also adjust third-party loggers. httpx/httpcore stay pinned to WARNING
# even in debug mode — at INFO/DEBUG they log full request URLs, which
# leaks secrets embedded in webhook URLs (Discord, generic webhooks, etc.).
logging.getLogger("sqlalchemy.engine").setLevel(logging.WARNING)
logging.getLogger("aiosqlite").setLevel(logging.WARNING)
logging.getLogger("httpcore").setLevel(logging.WARNING)
logging.getLogger("httpx").setLevel(logging.WARNING)
logging.getLogger("paho.mqtt").setLevel(logging.DEBUG if debug else logging.WARNING)
logger.info("Log level changed to %s", "DEBUG" if debug else "INFO")