From 0f15b2b8c868b0338172c9dcca9c271c90f45042 Mon Sep 17 00:00:00 2001 From: maziggy Date: Sun, 1 Feb 2026 16:20:07 +0100 Subject: [PATCH 1/4] Fixed CodeQL Alert #68: Stack trace exposure in archives.py --- backend/app/api/routes/archives.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/backend/app/api/routes/archives.py b/backend/app/api/routes/archives.py index 5bf950fa6..4d34a0508 100644 --- a/backend/app/api/routes/archives.py +++ b/backend/app/api/routes/archives.py @@ -901,7 +901,8 @@ async def rescan_all_archives(db: AsyncSession = Depends(get_db)): updated += 1 except Exception as e: - errors.append({"id": archive.id, "error": str(e)}) + logger.exception(f"Failed to rescan archive {archive.id}: {e}") + errors.append({"id": archive.id, "error": "Failed to parse 3MF file"}) await db.commit() return {"updated": updated, "errors": errors} @@ -944,7 +945,8 @@ async def backfill_content_hashes(db: AsyncSession = Depends(get_db)): archive.content_hash = ArchiveService.compute_file_hash(file_path) updated += 1 except Exception as e: - errors.append({"id": archive.id, "error": str(e)}) + logger.exception(f"Failed to compute hash for archive {archive.id}: {e}") + errors.append({"id": archive.id, "error": "Failed to compute hash"}) await db.commit() return {"updated": updated, "errors": errors} @@ -2134,7 +2136,8 @@ async def upload_archives_bulk( else: errors.append({"filename": file.filename, "error": "Failed to process"}) except Exception as e: - errors.append({"filename": file.filename, "error": str(e)}) + logger.exception(f"Failed to upload archive {file.filename}: {e}") + errors.append({"filename": file.filename, "error": "Failed to process file"}) finally: if temp_path.exists(): temp_path.unlink() From a9bb8ed8239602bf08a9914f85a09eeb2bf13d15 Mon Sep 17 00:00:00 2001 From: maziggy Date: Sun, 1 Feb 2026 16:26:55 +0100 Subject: [PATCH 2/4] Fix external spool ams_mapping2 slot_id (Issue #213) The ams_mapping2 format was incorrectly using the tray_id (254/255) as the slot_id for external spools. The printer expects slot_id to be the actual slot index (0 for main nozzle, 1 for deputy nozzle), not the tray_id value. Before: {"ams_id": 255, "slot_id": 254} <- invalid slot index After: {"ams_id": 255, "slot_id": 0} <- correct slot index This caused prints using external spool to fail immediately with error code 07FF_8007. Closes #213 --- backend/app/services/bambu_mqtt.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/backend/app/services/bambu_mqtt.py b/backend/app/services/bambu_mqtt.py index ece44bb81..ec27a3dc4 100644 --- a/backend/app/services/bambu_mqtt.py +++ b/backend/app/services/bambu_mqtt.py @@ -2038,8 +2038,9 @@ class BambuMQTTClient: ams_mapping2.append({"ams_id": 255, "slot_id": 255}) elif tray_id >= 254: # External spool: 254 = main nozzle, 255 = deputy nozzle - # External spools use ams_id=255 with slot_id matching tray_id - ams_mapping2.append({"ams_id": 255, "slot_id": tray_id}) + # For ams_mapping2, slot_id is 0 (main) or 1 (deputy), not the tray_id + external_slot = 0 if tray_id == 254 else 1 + ams_mapping2.append({"ams_id": 255, "slot_id": external_slot}) else: # Regular AMS tray: Global tray ID = (ams_id * 4) + slot_id ams_id = tray_id // 4 From 11d6c05d8ee391861ea79b81223ee769ddb0106c Mon Sep 17 00:00:00 2001 From: maziggy Date: Mon, 2 Feb 2026 06:36:03 +0100 Subject: [PATCH 3/4] Housekeeping --- docker-publish.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-publish.sh b/docker-publish.sh index 4132621e5..446ef8d5a 100755 --- a/docker-publish.sh +++ b/docker-publish.sh @@ -84,7 +84,7 @@ fi # Determine if this is a release version (includes betas for now) IS_RELEASE=false -if [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(b[0-9]+)?$ ]]; then +if [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?(b[0-9]+)?$ ]]; then IS_RELEASE=true fi From 09a405123a7f739736fdb0cf5959bc9d769376ce Mon Sep 17 00:00:00 2001 From: maziggy Date: Mon, 2 Feb 2026 08:18:54 +0100 Subject: [PATCH 4/4] Document intentional JWT secret storage (CodeQL Alert #69) Add explanatory comment for CodeQL alert about clear-text storage of JWT secret. This is intentional and secure: - JWT secrets must be readable by the application - File permissions set to 0600 (owner read/write only) - Standard practice for self-hosted apps (same as .env files) The alert should be dismissed in GitHub Security tab as "Won't fix". --- backend/app/core/auth.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/backend/app/core/auth.py b/backend/app/core/auth.py index 2dc5ec4e9..0386c1879 100644 --- a/backend/app/core/auth.py +++ b/backend/app/core/auth.py @@ -72,7 +72,10 @@ def _get_jwt_secret() -> str: # Try to save it try: data_dir.mkdir(parents=True, exist_ok=True) - secret_file.write_text(new_secret) + # Note: CodeQL flags this as "clear-text storage of sensitive information" but this is + # intentional and secure - JWT secrets must be readable by the app, we set 0600 permissions, + # and this is standard practice for self-hosted applications (same as .env files). + secret_file.write_text(new_secret) # nosec B105 - intentional secure storage # Restrict permissions (owner read/write only) secret_file.chmod(0o600) logger.info("Generated new JWT secret and saved to %s", secret_file)