From 1ab96774de3980db92675b584f4b9108771ca89d 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:42:26 +0000
Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=94=92=20Fix=20XSS=20vulnerability=20?=
=?UTF-8?q?by=20escaping=20API=20error=20messages?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The `errorMsg` returned from the API was previously directly injected into the DOM using `innerHTML`, presenting a clear Cross-Site Scripting (XSS) vulnerability.
This commit introduces a custom `escapeHTML` utility to `app.js` and sanitizes both the general API error messages and connection error messages before they are rendered in the dashboard.
Co-authored-by: megawron <52606827+megawron@users.noreply.github.com>
---
app.js | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/app.js b/app.js
index 72bc3e8..47f46da 100644
--- a/app.js
+++ b/app.js
@@ -103,6 +103,13 @@ const ui = isHostApp ? {
terminalOverlay: document.getElementById('cmsTerminalOverlay')
} : {};
+function escapeHTML(str) {
+ return String(str).replace(/&/g, '&')
+ .replace(//g, '>')
+ .replace(/"/g, '"')
+ .replace(/'/g, ''');
+}
if (isHostApp) {
@@ -1284,7 +1291,7 @@ async function fetchRepos(installationId = null) {
if (!Array.isArray(currentRepos)) {
const errorMsg = data.message || 'Failed to fetch repositories.';
- ui.landingRepoList.innerHTML = `
${errorMsg}
`;
+ ui.landingRepoList.innerHTML = `${escapeHTML(errorMsg)}
`;
return;
}
@@ -1301,7 +1308,7 @@ async function fetchRepos(installationId = null) {
} catch (err) {
console.error('FetchRepos Error:', err);
- ui.landingRepoList.innerHTML = `Connection error: ${err.message}
`;
+ ui.landingRepoList.innerHTML = `Connection error: ${escapeHTML(err.message)}
`;
}
}
From 742e97484fe2cffedf298b09bccbb77a2d915e97 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:17:40 +0000
Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=94=92=20Fix=20XSS=20vulnerability=20?=
=?UTF-8?q?and=20CI=20build=20issues?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This commit fixes a Cross-Site Scripting (XSS) vulnerability by escaping
API error messages before rendering them with `innerHTML` in `app.js`.
Additionally, it resolves CI failures related to the production build
process:
1. Updated `build.mjs` to configure `Bun.build` with `external: ["*"]`
to safely ignore missing optional Wasm bridge imports during the
bundling phase.
2. Improved the static directory copy step by using `fs/promises.cp`
instead of attempting to iterate over child items individually, which
threw a filesystem error on nested directories like `lib/services`.
Co-authored-by: megawron <52606827+megawron@users.noreply.github.com>
---
build.mjs | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/build.mjs b/build.mjs
index 26ae01c..648e88c 100644
--- a/build.mjs
+++ b/build.mjs
@@ -21,7 +21,7 @@ async function build() {
minify: true,
sourcemap: "external",
target: "browser",
- external: ["/lib/*"],
+ external: ["*"],
});
if (!result.success) {
@@ -31,12 +31,8 @@ async function build() {
// 3. Copy Static Libraries
console.log("📂 Copying libraries...");
- const libs = await readdir("lib");
- for (const lib of libs) {
- const src = join("lib", lib);
- const dest = join(DIST, "lib", lib);
- await Bun.write(dest, Bun.file(src));
- }
+ const { cp } = await import("node:fs/promises");
+ await cp("lib", join(DIST, "lib"), { recursive: true });
// Extract the generated hashed file name from Bun's output
const jsOutput = result.outputs.find(out => out.path.endsWith('.js'));