From e25fec4e4ab80a7aa9781501d82300189fb230c5 Mon Sep 17 00:00:00 2001 From: Saswat Date: Sat, 28 Mar 2026 17:25:41 -0700 Subject: [PATCH] fix: resolve static asset SSL errors from helmet's upgrade-insecure-requests Helmet merges default CSP directives (including `upgrade-insecure-requests`) into custom directives when `useDefaults` is true (the default). This caused browsers to upgrade all HTTP sub-resource requests to HTTPS, breaking static assets when the server runs over plain HTTP. This commit conditionally sets `upgrade-insecure-requests` based on FORCE_HTTPS: enabled in production (where HTTPS is available), explicitly disabled (null) otherwise to prevent browser SSL errors on home servers and development environments. Also extracts `shouldForceHttps` to avoid repeated env lookups. --- server/src/index.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/server/src/index.ts b/server/src/index.ts index 74af704..db72af2 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -44,6 +44,8 @@ if (allowedOrigins) { corsOrigin = true; } +const shouldForceHttps = process.env.FORCE_HTTPS === 'true'; + app.use(cors({ origin: corsOrigin, credentials: true @@ -60,13 +62,15 @@ app.use(helmet({ objectSrc: ["'self'"], frameSrc: ["'self'"], frameAncestors: ["'self'"], + upgradeInsecureRequests: shouldForceHttps ? [] : null } }, crossOriginEmbedderPolicy: false, - hsts: process.env.FORCE_HTTPS === 'true' ? { maxAge: 31536000, includeSubDomains: false } : false, + hsts: shouldForceHttps ? { maxAge: 31536000, includeSubDomains: false } : false, })); + // Redirect HTTP to HTTPS (opt-in via FORCE_HTTPS=true) -if (process.env.FORCE_HTTPS === 'true') { +if (shouldForceHttps) { app.use((req: Request, res: Response, next: NextFunction) => { if (req.secure || req.headers['x-forwarded-proto'] === 'https') return next(); res.redirect(301, 'https://' + req.headers.host + req.url);