fix(security): re-pin cached hub scripts to CVE-patched versions (+ HUB_BASE_URL override for cache mode) (#9387)

* 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) <noreply@anthropic.com>

* 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) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ruben Fiszel
2026-05-31 10:28:27 +02:00
committed by GitHub
parent d23d8374dd
commit edf340c4d4
2 changed files with 16 additions and 6 deletions
+10
View File
@@ -258,6 +258,15 @@ pub fn main() -> anyhow::Result<()> {
}
async fn cache_hub_scripts(file_path: Option<String>) -> 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.");
+6 -6
View File
@@ -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"
}