From dbbfdb7a187380700e269ba392a29a6a32cf3fdf Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 23 Apr 2026 13:25:04 +0000 Subject: [PATCH 1/4] =?UTF-8?q?=F0=9F=94=92=20Fix=20Path=20Traversal=20vul?= =?UTF-8?q?nerability=20in=20serve.js?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add decodeURIComponent to safely parse incoming paths - Use path.join to resolve relative requests against process.cwd() - Verify the normalized path strictly begins with the expected base directory - Issue a 403 Forbidden for malformed or out-of-bound traversal attempts - Address minor issue with query strings breaking static `/lib/` files - Fix prevents reading sensitive local files such as /etc/passwd or .env Co-authored-by: megawron <52606827+megawron@users.noreply.github.com> --- serve.js | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/serve.js b/serve.js index 0fe3dcc..c18e35e 100644 --- a/serve.js +++ b/serve.js @@ -292,16 +292,32 @@ const server = http.createServer((req, res) => { return; } - let filePath = '.' + req.url.split('?')[0]; + const basePath = process.cwd(); + let requestPath = req.url.split('?')[0]; + try { + requestPath = decodeURIComponent(requestPath); + } catch (e) { + res.writeHead(400, { 'Content-Type': 'text/plain' }); + res.end('Bad Request'); + return; + } + + let filePath = path.join(basePath, requestPath); + + // Security: Prevent path traversal + if (!filePath.startsWith(basePath) || (filePath !== basePath && !filePath.startsWith(basePath + path.sep))) { + res.writeHead(403, { 'Content-Type': 'text/plain' }); + res.end('Forbidden'); + return; + } // Map root to the main index.html (One-Pager) - if (filePath === './') { - filePath = './index.html'; + if (filePath === basePath || filePath === basePath + path.sep) { + filePath = path.join(basePath, 'index.html'); } - + // High-Performance Library Serving if (req.url.startsWith('/lib/')) { - filePath = '.' + req.url; res.setHeader('Cache-Control', 'public, max-age=31536000, immutable'); } From 8c12257a0647f7a926d4d70db42e84dbe048ddc4 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 23 Apr 2026 14:19:37 +0000 Subject: [PATCH 2/4] =?UTF-8?q?=F0=9F=94=92=20Fix=20Path=20Traversal=20vul?= =?UTF-8?q?nerability=20and=20build=20issues?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add decodeURIComponent to safely parse incoming paths in serve.js - Use path.join to resolve relative requests against process.cwd() - Verify the normalized path strictly begins with the expected base directory - Issue a 403 Forbidden for malformed or out-of-bound traversal attempts - Address minor issue with query strings breaking static `/lib/` files - Fix CI build script `build.mjs` failing when trying to write directories using Bun.write. Added fs/promises stat and cp to handle directories properly when copying the `lib` directory contents. Co-authored-by: megawron <52606827+megawron@users.noreply.github.com> --- build.mjs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/build.mjs b/build.mjs index 26ae01c..7c11c31 100644 --- a/build.mjs +++ b/build.mjs @@ -1,4 +1,4 @@ -import { rm, mkdir, readdir } from "node:fs/promises"; +import { rm, mkdir, readdir, stat, cp } from "node:fs/promises"; import { join } from "node:path"; const DIST = "dist"; @@ -35,7 +35,12 @@ async function build() { for (const lib of libs) { const src = join("lib", lib); const dest = join(DIST, "lib", lib); - await Bun.write(dest, Bun.file(src)); + const stats = await stat(src); + if (stats.isDirectory()) { + await cp(src, dest, { recursive: true }); + } else { + await Bun.write(dest, Bun.file(src)); + } } // Extract the generated hashed file name from Bun's output From b55c5c85b4668cc18a95fcc24bb6aa92c1e2561f Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 23 Apr 2026 14:38:07 +0000 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=94=92=20Fix=20Path=20Traversal=20vul?= =?UTF-8?q?nerability=20and=20build=20issues?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add decodeURIComponent to safely parse incoming paths in serve.js - Use path.join to resolve relative requests against process.cwd() - Verify the normalized path strictly begins with the expected base directory - Issue a 403 Forbidden for malformed or out-of-bound traversal attempts - Address minor issue with query strings breaking static `/lib/` files - Fix CI build script `build.mjs` failing when trying to write directories using Bun.write. Added fs/promises stat and cp to handle directories properly when copying the `lib` directory contents. - Compile WASM Rust module automatically as part of `build.mjs` to fix CI missing dependency error. Co-authored-by: megawron <52606827+megawron@users.noreply.github.com> --- build.mjs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/build.mjs b/build.mjs index 7c11c31..aed3239 100644 --- a/build.mjs +++ b/build.mjs @@ -7,12 +7,21 @@ const ASSETS = join(DIST, "assets"); async function build() { console.log("🚀 Starting ZeroCMS Production Build (via Bun)..."); - // 1. Clean and Create Directories + // 1. Compile WASM First + console.log("🦀 Compiling Rust WASM module..."); + const proc = Bun.spawn(["bash", "scripts/build_tagger.sh"]); + const exitCode = await proc.exited; + if (exitCode !== 0) { + console.error("❌ Failed to compile WASM module"); + process.exit(1); + } + + // 2. Clean and Create Directories await rm(DIST, { recursive: true, force: true }); await mkdir(ASSETS, { recursive: true }); await mkdir(join(DIST, "lib"), { recursive: true }); - // 2. Bundle Dashboard App + // 3. Bundle Dashboard App console.log("📦 Bundling app... "); const result = await Bun.build({ entrypoints: ["app.js"], From cb501fdd2f57d6b5f1f71ed7461a7fd6ae696bb9 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 23 Apr 2026 16:43:14 +0000 Subject: [PATCH 4/4] =?UTF-8?q?=F0=9F=94=92=20Fix=20Path=20Traversal=20vul?= =?UTF-8?q?nerability=20and=20build=20issues?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add decodeURIComponent to safely parse incoming paths in serve.js - Use path.join to resolve relative requests against process.cwd() - Verify the normalized path strictly begins with the expected base directory - Issue a 403 Forbidden for malformed or out-of-bound traversal attempts - Address minor issue with query strings breaking static `/lib/` files - Fix CI build script `build.mjs` failing when trying to write directories using Bun.write. Added fs/promises stat and cp to handle directories properly when copying the `lib` directory contents. - Compile WASM Rust module automatically as part of `build.mjs` to fix CI missing dependency error. Co-authored-by: megawron <52606827+megawron@users.noreply.github.com>