From edf340c4d4f18b16b142cb7deb67afa586f10946 Mon Sep 17 00:00:00 2001 From: Ruben Fiszel Date: Sun, 31 May 2026 10:28:27 +0200 Subject: [PATCH] fix(security): re-pin cached hub scripts to CVE-patched versions (+ HUB_BASE_URL override for cache mode) (#9387) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(cache): allow overriding hub base url via env in `cache` mode The `windmill cache hubPaths.json` prebuild step (run in the Dockerfile) never connects to the DB, so HUB_BASE_URL stays at its compiled default (https://hub.windmill.dev) — unlike server/worker modes which load it from the DB global setting. This made it impossible to point the prebuild cache step at a private or staging hub. Read HUB_BASE_URL from the environment at the start of cache_hub_scripts and store it into the existing HUB_BASE_URL ArcSwap (the same static the hub fetch functions read). No effect unless the env var is set and non-empty; server and worker modes are unchanged (they still use the DB setting). This also enables validating hub-script dependency changes end-to-end against a local fake-hub before pushing to the real hub. Co-Authored-By: Claude Opus 4.8 (1M context) * fix(security): re-pin cached hub scripts to patched versions windmill-integrations#133 was merged and pushed to the hub, minting new versions with regenerated (CVE-free) lockfiles. Bump the hubPaths.json pins so the prebuild cache step (`windmill cache`) fetches the patched lockfiles instead of the old vulnerable ones (the hub serves each version_id immutably, so the old pins keep returning the vulnerable deps until bumped). - slackErrorHandler 19741 -> 28241 - slackRecoveryHandler 9080 -> 28239 - slackSuccessHandler 28220 -> 28240 - smtpReport 9086 -> 28242 - appReport 28076 -> 28243 (puppeteer screenshot script) - gitInitRepo 28219 -> 28229 (already-fixed hub version; pin was stale) Validated end-to-end against the real hub: `windmill cache` with these pins produces a clean cache_nomount/bun (axios 1.16.1, form-data 4.0.5, follow-redirects 1.16.0, nodemailer 8.0.10, ws 8.21.0, svelte 5.55.8, devalue 5.8.1; basic-ftp and ip-address no longer pulled). No vulnerable versions remain. Co-Authored-By: Claude Opus 4.8 (1M context) --------- Co-authored-by: Claude Opus 4.8 (1M context) --- backend/src/main.rs | 10 ++++++++++ frontend/src/lib/hubPaths.json | 12 ++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/backend/src/main.rs b/backend/src/main.rs index 87285e2ae1..29bea050ed 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -258,6 +258,15 @@ pub fn main() -> anyhow::Result<()> { } async fn cache_hub_scripts(file_path: Option) -> anyhow::Result<()> { + // The `cache` CLI mode never connects to the DB, so HUB_BASE_URL keeps its + // compiled default. Allow overriding it via env so the prebuild cache step can + // be pointed at a private/staging hub (e.g. a local proxy for testing). + if let Ok(hub_base_url) = std::env::var("HUB_BASE_URL") { + if !hub_base_url.is_empty() { + tracing::info!("Overriding hub base url from env: {hub_base_url}"); + windmill_common::HUB_BASE_URL.store(std::sync::Arc::new(hub_base_url)); + } + } let file_path = file_path.unwrap_or("./hubPaths.json".to_string()); let mut file = File::open(&file_path) .await @@ -567,6 +576,7 @@ fn print_help() { println!(" RUN_UPDATE_CA_CERTIFICATE_AT_START = false Run system CA update at startup"); println!(" RUN_UPDATE_CA_CERTIFICATE_PATH = /usr/sbin/update-ca-certificates Path to CA update tool"); println!(" SYNC_CACHED_RT = false Sync cached resource types to admins workspace on server start"); + println!(" HUB_BASE_URL = https://hub.windmill.dev Hub to fetch scripts from in `cache` mode (server/worker use the DB setting instead)"); println!(); println!("Notes:"); println!("- Advanced and less commonly used settings are managed via the database and are omitted here."); diff --git a/frontend/src/lib/hubPaths.json b/frontend/src/lib/hubPaths.json index 902a90c9d1..2ae15d931b 100644 --- a/frontend/src/lib/hubPaths.json +++ b/frontend/src/lib/hubPaths.json @@ -1,16 +1,16 @@ { "gitSyncTest": "hub/28184/git-repo-test-read-write-windmill", - "gitInitRepo": "hub/28219/git-sync%3A-init-repository-windmill", - "slackErrorHandler": "hub/19741/workspace-or-schedule-error-handler-slack", + "gitInitRepo": "hub/28229/git-sync%3A-init-repository-windmill", + "slackErrorHandler": "hub/28241/workspace-or-schedule-error-handler-slack", "emailErrorHandler": "hub/19795/workspace-or-error-handler-email", - "slackRecoveryHandler": "hub/9080/slack/schedule-recovery-handler-slack", - "slackSuccessHandler": "hub/28220/slack/schedule-success-handler-slack", + "slackRecoveryHandler": "hub/28239/slack/schedule-recovery-handler-slack", + "slackSuccessHandler": "hub/28240/slack/schedule-success-handler-slack", "teamsErrorHandler": "hub/19742/workspace-or-schedule-error-handler-teams", "teamsRecoveryHandler": "hub/11593/schedule-recovery-handler-teams", "teamsSuccessHandler": "hub/11596/schedule-success-handler-teams", "slackReport": "hub/9084/slack", "discordReport": "hub/9085/discord", - "smtpReport": "hub/9086/smtp", - "appReport": "hub/28076/app-report", + "smtpReport": "hub/28242/smtp", + "appReport": "hub/28243/app-report", "cloneRepoToS3forGitRepoViewer": "hub/28216/clone_repo_and_upload_to_instance_storage" }