Skip to content

Conversation

@fangsmile
Copy link
Contributor

This reverts commit 043d740.

[中文版模板 / Chinese template]

🤔 This is a ...

  • New feature
  • Bug fix
  • TypeScript definition update
  • Bundle size optimization
  • Performance optimization
  • Enhancement feature
  • Refactoring
  • Update dependency
  • Code style optimization
  • Test Case
  • Branch merge
  • Site / documentation update
  • Demo update
  • Workflow
  • Chore
  • Release
  • Other (about what?)

🔗 Related issue link

💡 Background and solution

📝 Changelog

Language Changelog
🇺🇸 English
🇨🇳 Chinese

☑️ Self-Check before Merge

⚠️ Please check all items below before requesting a reviewing. ⚠️

  • Doc is updated/provided or not needed
  • Demo is updated/provided or not needed
  • TypeScript definition is updated/provided or not needed
  • Changelog is provided or not needed

🚀 Summary

copilot:summary

🔍 Walkthrough

copilot:walkthrough

if (logOutput) {
const timestamp = new Date().toLocaleTimeString();
const color = type === 'error' ? '#ff6b6b' : type === 'success' ? '#51cf66' : '#74c0fc';
logOutput.innerHTML += `<span style="color:${color}">[${timestamp}] ${message}</span>\n`;

Check failure

Code scanning / CodeQL

DOM text reinterpreted as HTML High

DOM text
is reinterpreted as HTML without escaping meta-characters.
DOM text is reinterpreted as HTML without escaping meta-characters.

Copilot Autofix

AI 18 days ago

In general, to fix "DOM text reinterpreted as HTML" issues, avoid passing untrusted text into APIs that interpret strings as HTML (innerHTML, jQuery $() with HTML, etc.). Instead, use DOM methods that operate on text (textContent, createTextNode) and separate presentation (styles, structure) from content. If markup is required, sanitize untrusted data before insertion with a robust HTML sanitizer.

For this specific case, the best fix is to stop concatenating log lines into innerHTML and instead create DOM elements per log entry. We can:

  • Remove the string template with embedded ${message}.
  • Create a <span> element, set its style.color to color.
  • Set its textContent to the formatted string [timestamp] message, which ensures that any HTML-like characters in message are escaped.
  • Append this span and a line break (<br>) (or wrap logs in block elements) to logOutput via appendChild, preserving existing functionality (colored, timestamped lines and scrolling behavior) without interpreting message as HTML.

Concretely, in packages/vtable-mcp-server/examples/main.ts, edit the log function around line 15:

  • Replace the logOutput.innerHTML += ... line with DOM-manipulation code that uses textContent and appendChild.
  • Keep the rest of the function (timestamp, color selection, scroll behavior, console.log) unchanged.

No new methods or external libraries are strictly needed; this can be accomplished with standard DOM APIs.

Suggested changeset 1
packages/vtable-mcp-server/examples/main.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/packages/vtable-mcp-server/examples/main.ts b/packages/vtable-mcp-server/examples/main.ts
--- a/packages/vtable-mcp-server/examples/main.ts
+++ b/packages/vtable-mcp-server/examples/main.ts
@@ -12,7 +12,11 @@
   if (logOutput) {
     const timestamp = new Date().toLocaleTimeString();
     const color = type === 'error' ? '#ff6b6b' : type === 'success' ? '#51cf66' : '#74c0fc';
-    logOutput.innerHTML += `<span style="color:${color}">[${timestamp}] ${message}</span>\n`;
+    const span = document.createElement('span');
+    span.style.color = color;
+    span.textContent = `[${timestamp}] ${message}`;
+    logOutput.appendChild(span);
+    logOutput.appendChild(document.createElement('br'));
     logOutput.scrollTop = logOutput.scrollHeight;
   }
   // eslint-disable-next-line no-console
EOF
@@ -12,7 +12,11 @@
if (logOutput) {
const timestamp = new Date().toLocaleTimeString();
const color = type === 'error' ? '#ff6b6b' : type === 'success' ? '#51cf66' : '#74c0fc';
logOutput.innerHTML += `<span style="color:${color}">[${timestamp}] ${message}</span>\n`;
const span = document.createElement('span');
span.style.color = color;
span.textContent = `[${timestamp}] ${message}`;
logOutput.appendChild(span);
logOutput.appendChild(document.createElement('br'));
logOutput.scrollTop = logOutput.scrollHeight;
}
// eslint-disable-next-line no-console
Copilot is powered by AI and may make mistakes. Always verify output.
// eslint-disable-next-line no-console
console.log('[mcp-smoke-http] endpoint:', endpoint);
// eslint-disable-next-line no-console
console.log('[mcp-smoke-http] session:', SESSION_ID);

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This logs sensitive data returned by
process environment
as clear text.

Copilot Autofix

AI 18 days ago

In general, to fix clear-text logging of sensitive information, avoid logging the raw value; either remove the log entirely, or log only non-sensitive derivatives (e.g., presence, length, or a truncated/hash form) that are sufficient for diagnostics. For environment-derived secrets or session IDs, a common approach is to log whether they are set and maybe a short, non-sensitive prefix, not the full value.

For this specific file, the minimal, non-breaking fix is to change the logging of SESSION_ID on line 21 so it no longer prints the full value. The script only uses this log for debugging; the actual behavior (sending SESSION_ID in the request body) does not depend on the log output. A good compromise is to either remove the session log or replace it with a redacted form such as a boolean “set/not set” plus a short prefix. I’ll keep a helpful log while avoiding exposure by logging either [REDACTED] when long, or a truncated version:

  • Add a small helper inside main (or just above the log) to compute a safe display string.
  • Replace console.log('[mcp-smoke-http] session:', SESSION_ID); with a version that logs a redacted representation, e.g., [mcp-smoke-http] session: [REDACTED] (length=...) or a short prefix and ***.

No new imports or dependencies are needed; we can do this with plain JavaScript.


Suggested changeset 1
packages/vtable-mcp-cli/scripts/mcp-smoke-http.js

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/packages/vtable-mcp-cli/scripts/mcp-smoke-http.js b/packages/vtable-mcp-cli/scripts/mcp-smoke-http.js
--- a/packages/vtable-mcp-cli/scripts/mcp-smoke-http.js
+++ b/packages/vtable-mcp-cli/scripts/mcp-smoke-http.js
@@ -17,8 +17,12 @@
   const endpoint = `${MCP_SERVER_URL}/mcp`;
   // eslint-disable-next-line no-console
   console.log('[mcp-smoke-http] endpoint:', endpoint);
+  const sessionForLog =
+    SESSION_ID === 'default'
+      ? 'default'
+      : `${String(SESSION_ID).slice(0, 4)}... [REDACTED]`;
   // eslint-disable-next-line no-console
-  console.log('[mcp-smoke-http] session:', SESSION_ID);
+  console.log('[mcp-smoke-http] session:', sessionForLog);
 
   const setRes = await fetch(endpoint, {
     method: 'POST',
EOF
@@ -17,8 +17,12 @@
const endpoint = `${MCP_SERVER_URL}/mcp`;
// eslint-disable-next-line no-console
console.log('[mcp-smoke-http] endpoint:', endpoint);
const sessionForLog =
SESSION_ID === 'default'
? 'default'
: `${String(SESSION_ID).slice(0, 4)}... [REDACTED]`;
// eslint-disable-next-line no-console
console.log('[mcp-smoke-http] session:', SESSION_ID);
console.log('[mcp-smoke-http] session:', sessionForLog);

const setRes = await fetch(endpoint, {
method: 'POST',
Copilot is powered by AI and may make mistakes. Always verify output.

function log(...args) {
// eslint-disable-next-line no-console
console.log('[mcp-smoke]', ...args);

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This logs sensitive data returned by
process environment
as clear text.
This logs sensitive data returned by
process environment
as clear text.

Copilot Autofix

AI 18 days ago

In general, to fix clear‑text logging of sensitive information, avoid passing potentially sensitive values (such as secrets, tokens, session IDs, etc.) directly to logging functions. Either remove them from log messages altogether or replace them with non‑sensitive metadata (e.g., whether they are set, their length, or a redacted/hashed form).

For this specific code, the problematic flow is SESSION_IDlogconsole.log. We should stop logging the raw SESSION_ID value. The simplest change that preserves functionality is to adjust the logging call in runWsOnly so it does not include the clear‑text session ID. For example, we can log just that a session ID is set (and optionally whether it is the default) without printing its actual value. This requires editing only the log('mode=ws', 'ws=', WS_URL, 'session=', SESSION_ID); line. No new methods or imports are needed.

Concretely:

  • In packages/vtable-mcp-server/scripts/mcp-smoke.js, change the first log line in runWsOnly so that it no longer passes SESSION_ID directly; instead log some safe metadata such as "session=<redacted>" and whether it equals 'default'. All other logging can remain as is, since the taint path is through that argument.
Suggested changeset 1
packages/vtable-mcp-server/scripts/mcp-smoke.js

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/packages/vtable-mcp-server/scripts/mcp-smoke.js b/packages/vtable-mcp-server/scripts/mcp-smoke.js
--- a/packages/vtable-mcp-server/scripts/mcp-smoke.js
+++ b/packages/vtable-mcp-server/scripts/mcp-smoke.js
@@ -137,7 +137,7 @@
 }
 
 async function runWsOnly() {
-  log('mode=ws', 'ws=', WS_URL, 'session=', SESSION_ID);
+  log('mode=ws', 'ws=', WS_URL, 'session=<redacted>', `session_is_default=${SESSION_ID === 'default'}`);
   const ws = new WebSocket(`${WS_URL}?session_id=${encodeURIComponent(SESSION_ID)}`);
   ws.on('open', () => {
     log('ws open');
EOF
@@ -137,7 +137,7 @@
}

async function runWsOnly() {
log('mode=ws', 'ws=', WS_URL, 'session=', SESSION_ID);
log('mode=ws', 'ws=', WS_URL, 'session=<redacted>', `session_is_default=${SESSION_ID === 'default'}`);
const ws = new WebSocket(`${WS_URL}?session_id=${encodeURIComponent(SESSION_ID)}`);
ws.on('open', () => {
log('ws open');
Copilot is powered by AI and may make mistakes. Always verify output.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants